ES8的Java API client 8.0 简单示例操作 Elasticsearch

1.加入依赖

java 复制代码
      <dependency>
            <groupId>co.elastic.clients</groupId>
            <artifactId>elasticsearch-java</artifactId>
            <version>8.12.2</version>
        </dependency>

2.配置类

java 复制代码
@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

前提:

注入ElasticsearchClient

java 复制代码
@Autowired
private ElasticsearchClient client;

3.1 创建索引

java 复制代码
 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 删除索引

java 复制代码
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查询索引

java 复制代码
 public void queryIndex() throws IOException {
        //1.lambda
        //查询单个
        Map<String, IndexState> tttIndex = client.indices().get(req -> req.index("ttt")).result();
        //查询索引
        Set<String> 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<String, IndexState> result = client.indices().get(getIndexRequest).result();
    }

3.4 插入文档

java 复制代码
 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<Goods> addIndexRequestOf = IndexRequest.of(t -> t.id(goods.getSku()).document(goods).index("goods"));
        IndexRequest<Goods> addIndexRequest = new IndexRequest<>.Builder()
                .index("goods")
                .id(goods.getSku())
                .document(goods).build();
        IndexResponse index = client.index(addIndexRequest);

    }

3.5 批量插入文档

java 复制代码
public void addBatchDoc() throws IOException {

        List<Goods> 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查询文档

java 复制代码
public void queryDoc() throws IOException {
        //1.lambda
        GetResponse<Goods> 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<Goods> response1 = client.get(request, Goods.class);
        if (response.found()){
            Goods source = response.source();
            System.out.println(source);
        }
    }

3.7修改文档

java 复制代码
 public void updateDoc() throws IOException {
        //全量
        Goods goods = new Goods("1","2",3.0);
        UpdateResponse<Goods> update = client.update(u -> u
                        .doc(goods)
                        .id(goods.getSku())
                , Goods.class);
        //of
        UpdateRequest<Object, Object> of = UpdateRequest.of(u -> u.id(goods.getSku()).doc(goods));
        UpdateResponse<Object> update1 = client.update(of, Goods.class);
    }

3.8删除文档

java 复制代码
   */
    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 匹配查询

java 复制代码
public void query() throws IOException {
        String text = "华为mate60";
        SearchResponse<Goods> 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<Goods> 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<Hit<Goods>> hits = response.hits().hits();
        for (Hit<Goods> hit : hits) {
            Goods goods = hit.source();
            System.out.println(goods);
        }
    }

3.10 多精确terms

java 复制代码
public void terms(){
        List<FieldValue> 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 布尔查询

java 复制代码
@Slf4j
@Service
public class EsTest {

    @Autowired
    private ElasticsearchClient client;

    
    /**
     * bool
     */
    public void boolQuery() throws IOException {
        Map<String, HighlightField> map = new HashMap<>();
        map.put("title", HighlightField.of(hf -> hf.preTags("<em>").postTags("<em/>")));
        map.put("description", HighlightField.of(hf -> hf.preTags("<em>").postTags("<em/>")
                .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<Goods> 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<Goods> response = client.search(of, Goods.class);
        List<Hit<Goods>> hits = response.hits().hits();
        for (Hit<Goods> hit : hits) {
            Goods goods = hit.source();
            if (goods == null){
                continue;
            }
            Map<String, List<String>> highlightList = hit.highlight();
            highlightList.forEach((key, Value)->{
                if (Objects.equals(key,goods.getName())){
                    //存入
                }else {
                    //无高亮
                }
               }
            );
            System.out.println(goods);
        }

    }
    
}

3.12构建排序

java 复制代码
/**
     * 构建排序
     */
    private List<SortOptions> 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();
        }

    }

...........

相关推荐
哎呦没15 分钟前
SpringBoot框架下的资产管理自动化
java·spring boot·后端
m0_571957582 小时前
Java | Leetcode Java题解之第543题二叉树的直径
java·leetcode·题解
一点媛艺3 小时前
Kotlin函数由易到难
开发语言·python·kotlin
姑苏风3 小时前
《Kotlin实战》-附录
android·开发语言·kotlin
奋斗的小花生4 小时前
c++ 多态性
开发语言·c++
魔道不误砍柴功4 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
NiNg_1_2344 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
闲晨4 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
老猿讲编程5 小时前
一个例子来说明Ada语言的实时性支持
开发语言·ada
Chrikk6 小时前
Go-性能调优实战案例
开发语言·后端·golang