1.加入依赖
-
-
co.elastic.clients -
elasticsearch-java -
8.12.2 -
2.配置类
-
-
- @Slf4j
- @Configuration
- public class ElasticSearchConfig {
- @Value("${elasticsearch.hosts}")
- private String hosts;
- @Value("${elasticsearch.port}")
- private int port;
- @Value("${elasticsearch.username}")
- private String username;
- @Value("${elasticsearch.password}")
- private String password;
- @Value("${elasticsearch.apikey:''}")
- private String apikey;
-
- /**
- * 单节点没密码连接
- *
- * @return
- */
- @Bean
- public ElasticsearchClient elasticsearchClient() {
- String[] servers = hosts.split(",");
- int len = servers.length;
- if (0 == len) {
- log.error("ElasticsearchClient 配置错误!");
- }
- ElasticsearchTransport transport = null;
- // 不是集群时
- if (1 == len) {
- // 无账号、密码
- if (StringUtils.isEmpty(username) && StringUtils.isEmpty(password)) {
- RestClient client = RestClient.builder(new HttpHost(servers[0], port, "http"))
- .setHttpClientConfigCallback(httpClientBuilder
- ->httpClientBuilder.setDefaultHeaders(
- Collections.singletonList(new BasicHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString())))
- .addInterceptorLast((HttpResponseInterceptor) (response, context)
- -> response.addHeader("X-Elastic-Product", "Elasticsearch")))
- .build();
- transport = new RestClientTransport(client, new JacksonJsonpMapper());
- } else {
- // 账号密码的配置
- final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
- credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
- // 自签证书的设置,并且还包含了账号密码
- RestClientBuilder.HttpClientConfigCallback callback = httpAsyncClientBuilder -> httpAsyncClientBuilder
- .setDefaultCredentialsProvider(credentialsProvider)
- .addInterceptorLast(
- (HttpResponseInterceptor)
- (response, context) ->
- response.addHeader("X-Elastic-Product", "Elasticsearch"));
-
- RestClient client = RestClient.builder(new HttpHost(servers[0], port, "http"))
- .setHttpClientConfigCallback(callback)
- .build();
- transport = new RestClientTransport(client, new JacksonJsonpMapper());
- }
- } else {
- // 集群时无账号、密码
- if (StringUtils.isEmpty(username) && StringUtils.isEmpty(password)) {
- transport = getElasticsearchTransport(toHttpHost());
- } else {
- transport = getElasticsearchTransport(username, password, toHttpHost());
- }
- }
- return new ElasticsearchClient(transport);
- }
-
-
- private HttpHost[] toHttpHost() {
- if (hosts.split(",").length == 0) {
- throw new RuntimeException("invalid elasticsearch configuration");
- }
- String[] hostArray = hosts.split(",");
- HttpHost[] httpHosts = new HttpHost[hostArray.length];
- HttpHost httpHost;
- for (int i = 0; i < hostArray.length; i++) {
- String[] strings = hostArray[i].split(":");
- httpHost = new HttpHost(strings[0], Integer.parseInt(strings[1]), "http");
- httpHosts[i] = httpHost;
- }
- return httpHosts;
- }
-
- private static ElasticsearchTransport getElasticsearchTransport(String username, String password, HttpHost... hosts) {
- // 账号密码的配置
- final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
- credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
-
- // 自签证书的设置,并且还包含了账号密码
- RestClientBuilder.HttpClientConfigCallback callback = httpAsyncClientBuilder -> httpAsyncClientBuilder
- .setSSLContext(buildSSLContext())
- .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
- .setDefaultCredentialsProvider(credentialsProvider)
- .setDefaultHeaders(
- Stream.of(new BasicHeader(
- HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString())).collect(toList())
- ).addInterceptorLast(
- (HttpResponseInterceptor)
- (response, context) ->
- response.addHeader("X-Elastic-Product", "Elasticsearch"))
- .addInterceptorLast((HttpResponseInterceptor) (response, context)
- -> response.addHeader("X-Elastic-Product", "Elasticsearch"));
- // 用builder创建RestClient对象
- RestClient client = RestClient
- .builder(hosts)
- .setHttpClientConfigCallback(callback)
- .build();
-
- return new RestClientTransport(client, new JacksonJsonpMapper());
- }
-
- private static ElasticsearchTransport getElasticsearchTransport(HttpHost... hosts) {
- // 用builder创建RestClient对象
- RestClient client = RestClient
- .builder(hosts)
- .build();
-
- return new RestClientTransport(client, new JacksonJsonpMapper());
- }
-
- private static SSLContext buildSSLContext() {
- ClassPathResource resource = new ClassPathResource("es01.crt");
- SSLContext sslContext = null;
- try {
- CertificateFactory factory = CertificateFactory.getInstance("X.509");
- Certificate trustedCa;
- try (InputStream is = resource.getInputStream()) {
- trustedCa = factory.generateCertificate(is);
- }
- KeyStore trustStore = KeyStore.getInstance("pkcs12");
- trustStore.load(null, null);
- trustStore.setCertificateEntry("ca", trustedCa);
- SSLContextBuilder sslContextBuilder = SSLContexts.custom().loadTrustMaterial(trustStore, null);
- sslContext = sslContextBuilder.build();
- } catch (CertificateException | IOException | KeyStoreException | NoSuchAlgorithmException |
- KeyManagementException e) {
- log.error("ES连接认证失败", e);
- }
- return sslContext;
- }
- }
3.相关api
前提:
- @Autowired
- private ElasticsearchClient client;
3.1 创建索引
- public void createIndex() throws IOException {
- ElasticsearchIndicesClient indices = client.indices();
- //是否存在
- //1.lambda
- boolean isExit = indices.exists(req -> req.index("ttt")).value();
- //2.builder,of
- ExistsRequest existsRequestOf = ExistsRequest.of(req -> req.index("ttt"));
- ExistsRequest existsRequest = new ExistsRequest.Builder().index("ttt").build();
- boolean builderExist = indices.exists(existsRequest).value();
- if (isExit){
- log.info("已经存在ttt");
- }else {
- //1.lambda
- boolean isSuccess = indices.create(req -> req.index("ttt")).acknowledged();
- //2.builder,of
- CreateIndexRequest createIndexRequestOf = CreateIndexRequest.of(req -> req.index("ttt"));
- CreateIndexRequest createIndexRequest = new CreateIndexRequest.Builder().index("ttt").build();
- boolean buildIsSuccess = indices.create(createIndexRequest).acknowledged();
- if (isSuccess){
- log.info("创建成功");
- }else {
- log.info("创建失败");
- }
- }
- }
3.2 删除索引
- public void deleteIndex() throws IOException {
- //1.lambda
- boolean isSuccess = client.indices().delete(req -> req.index("ttt")).acknowledged();
- //2.builder,of
- DeleteIndexRequest deleteRequestOf = DeleteIndexRequest.of(req -> req.index("ttt"));
- DeleteIndexRequest deleteRequest = new DeleteIndexRequest.Builder().index("ttt").build();
- boolean buildDeleteRequest = client.indices().delete(deleteRequest).acknowledged();
- }
3.3查询索引
- public void queryIndex() throws IOException {
- //1.lambda
- //查询单个
- Map
tttIndex = client.indices().get(req -> req.index("ttt")).result(); - //查询索引
- Set
all = client.indices().get(req -> req.index("*")).result().keySet(); - //2.builder
- GetIndexRequest getIndexRequestOf = GetIndexRequest.of(req -> req.index("ttt"));
- GetIndexRequest getIndexRequest = new GetIndexRequest.Builder().index("ttt").build();
- Map
result = client.indices().get(getIndexRequest).result(); - }
3.4 插入文档
- public void addDoc() throws IOException {
- Goods goods = new Goods("3212334","华为mate60", 9999.0);
-
- //1.lambda
- client.index(i->i
- .index("goods")
- .id(goods.getSku())
- .document(goods));
- //2.builder-of
- IndexRequest
addIndexRequestOf = IndexRequest.of(t -> t.id(goods.getSku()).document(goods).index("goods")); - IndexRequest
addIndexRequest = new IndexRequest<>.Builder() - .index("goods")
- .id(goods.getSku())
- .document(goods).build();
- IndexResponse index = client.index(addIndexRequest);
-
- }
3.5 批量插入文档
- public void addBatchDoc() throws IOException {
-
- List
goodsList = List.of(new Goods("1","手机",999.0)); - BulkRequest.Builder br = new BulkRequest.Builder();
- for (Goods goods : goodsList) {
- br.operations(op->op.
- index(idx->idx.index("goods")
- .id(goods.getSku())
- .document(goods)));
- }
- BulkResponse result = client.bulk(br.build());
- // Log errors, if any
- if (result.errors()) {
- log.error("Bulk had errors");
- for (BulkResponseItem item: result.items()) {
- if (item.error() != null) {
- log.error(item.error().reason());
- }
- }
- }
- }
3.6查询文档
- public void queryDoc() throws IOException {
- //1.lambda
- GetResponse
response = client.get(g -> g - .index("goods")
- .id("00000")
- , Goods.class);
- //2.builder,of
- GetRequest request = GetRequest.of(g -> g.index("goods").id("00000"));
-
- GetRequest ofRequest = new GetRequest.Builder().index("goods").id("00000").build();
-
-
- GetResponse
response1 = client.get(request, Goods.class); - if (response.found()){
- Goods source = response.source();
- System.out.println(source);
- }
- }
3.7修改文档
- public void updateDoc() throws IOException {
- //全量
- Goods goods = new Goods("1","2",3.0);
- UpdateResponse
update = client.update(u -> u - .doc(goods)
- .id(goods.getSku())
- , Goods.class);
- //of
- UpdateRequest
- UpdateResponse
- }
3.8删除文档
- */
- public void deleteDoc() throws IOException {
- DeleteResponse goods = client.delete(d -> d
- .index("goods")
- .id("0000"));
-
- //of
- DeleteRequest deleteRequest = DeleteRequest.of(d -> d.index("goods").id("0000"));
- client.delete(deleteRequest);
- }
3.9 DSL 匹配查询
- public void query() throws IOException {
- String text = "华为mate60";
- SearchResponse
response = client.search(s -> s - .index("goods")
- .query(q -> q
- .match(m -> m
- .field("name")
- .query(text))
- )
- , Goods.class);
-
- //of
- SearchRequest request = SearchRequest.of(s -> s.index("goods")
- .query(q -> q
- .match(m ->
- m.field("").field(""))
- ));
- SearchResponse
search = client.search(request, Goods.class); - //结果
- //总数
- TotalHits total = response.hits().total();
- assert total != null;
- boolean isExactResult = total.relation() == TotalHitsRelation.Eq;
- if (isExactResult) {
- log.info("找到 " + total.value() + " 个结果");
- } else {
- log.info("找到超过 " + total.value() + " 个结果");
- }
- List
> hits = response.hits().hits(); - for (Hit
hit : hits) { - Goods goods = hit.source();
- System.out.println(goods);
- }
- }
3.10 多精确terms
- public void terms(){
- List
v = new ArrayList<>(); - FieldValue tag2 = FieldValue.of("tag2");
- FieldValue tag1 = FieldValue.of("tag1");
- v.add(tag1);v.add(tag2);
- TermsQuery tags = TermsQuery.of(t -> t.field("tags").terms(tm -> tm.value(v)));
- SearchRequest of = SearchRequest.of(s -> s.index("goods")
- .query(q -> q
- .bool(b -> b
- .must(m -> m
- .terms(tags)
- )
- .should(sh -> sh
- .match(ma -> ma
- .field("")
- .query("")
- )
- )
- )
- )
- .from(0)
- .size(10)
-
- );
-
- }
3.11 布尔查询
-
-
-
- @Slf4j
- @Service
- public class EsTest {
-
- @Autowired
- private ElasticsearchClient client;
-
-
- /**
- * bool
- */
- public void boolQuery() throws IOException {
- Map
map = new HashMap<>(); - map.put("title", HighlightField.of(hf -> hf.preTags("").postTags("")));
- map.put("description", HighlightField.of(hf -> hf.preTags("").postTags("")
- .numberOfFragments(4).fragmentSize(50)));
- //numberOfFragments(4),表示将字段分割为最多4个片段,并设置 fragmentSize(50),表示每个片段的大小为50个字符。
-
- Highlight highlight = Highlight.of(
- h -> h.type(HighlighterType.Unified)
- .fields(map)
- .fragmentSize(50)//设置默认的高亮片段大小为50个字符,如果字段没有单独设置,则使用此默认值。
- .numberOfFragments(5)//设置每个字段的最大高亮片段数为5个。
- );
-
- String text = "华为mate60";
- SearchResponse
search = client.search(s -> s - .index("goods")
- .query(q -> q
- .bool(b -> b
- .must(m -> m
- .term(t -> t
- .field("品牌")
- .value("华为")
- )
- )
- .should(sd -> sd
- .match(mh -> mh
- .field("name")
- .query("mate60")))
- )
- )
- .from(0)
- .size(10)
- .highlight(highlight)
- , Goods.class);
- //of
- SearchRequest of = SearchRequest.of(s -> s.index("goods")
- .query(q -> q
- .bool(b -> b
- .must(m -> m
- .term(t -> t.field("品牌")
- .value("华为")
- )
- )
- .should(sh -> sh
- .match(ma -> ma
- .field("")
- .query("")
- )
- )
- )
- )
- .from(0)
- .size(10)
- .highlight(highlight)
-
- );
-
- SearchResponse
response = client.search(of, Goods.class); - List
> hits = response.hits().hits(); - for (Hit
hit : hits) { - Goods goods = hit.source();
- if (goods == null){
- continue;
- }
- Map
> highlightList = hit.highlight(); - highlightList.forEach((key, Value)->{
- if (Objects.equals(key,goods.getName())){
- //存入
- }else {
- //无高亮
- }
- }
- );
- System.out.println(goods);
- }
-
- }
-
- }
3.12构建排序
- /**
- * 构建排序
- */
- private List
buildSort(SearchDTO dto) { - if (dto.getTimeSort() != null){
- SortOptions sortOptions ;
- if (dto.getTimeSort() == 0){
- sortOptions = SortOptions.of(s -> s.field(FieldSort.of(f -> f.field(SearchConstants.TIMESTAMP).order(SortOrder.Asc))));
- }else {
- sortOptions = SortOptions.of(s -> s.field(FieldSort.of(f -> f.field(SearchConstants.TIMESTAMP).order(SortOrder.Desc))));
- }
- return List.of(sortOptions);
- }else {
- return Collections.emptyList();
- }
-
- }
...........
评论记录:
回复评论: