ElasticSearch的Java Client集成

本文详细介绍如何使用Java REST High-Level Client对Elasticsearch进行多种高级查询操作,包括全文检索、精确查询、布尔查询、过滤查询及高亮显示等,通过具体代码示例展示查询效果。

一、Java Client 集成

介绍如何使用Java REST High-Level Client对Elasticsearch进行多种高级查询操作,包括全文检索、精确查询、布尔查询、过滤查询及高亮显示等,通过具体代码示例展示查询效果。(以7.10版本为例)

1、创建Maven项目添加坐标

    <dependencies>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.10.0</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.20.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.20.0</version>
        </dependency>
    </dependencies>

2、编写测试类

public class ClientTest {

private static final RequestOptions COMMON_OPTIONS;
private static final String USERNAME = "****";
private static final String PASSWORD = "****";
private static final String HTTP_HOST = "*************";
private static final Integer PORT = 9200;
private static final String INDEX_NAME = "******";
private static final String TYPE_NAME = "********";
private static final String DOC_ID = "";//根据需要更改

static {
    RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();

    // 默认缓存限制为100MB,此处修改为30MB。
    builder.setHttpAsyncResponseConsumerFactory(
            new HttpAsyncResponseConsumerFactory
                    .HeapBufferedResponseConsumerFactory(30 * 1024 * 1024));
    COMMON_OPTIONS = builder.build();
}


//抽取共用代码(认证,创建客户端对象)
private RestHighLevelClient getHighClient() {
    // 阿里云ES集群需要basic auth验证。
    final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
    //访问用户名和密码为您创建阿里云Elasticsearch实例时设置的用户名和密码,也是Kibana控制台的登录用户名和密码。
    credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(USERNAME, PASSWORD));

    // 通过builder创建rest client,配置http client的HttpClientConfigCallback。
    // 单击所创建的Elasticsearch实例ID,在基本信息页面获取公网地址,即为ES集群地址。
    RestClientBuilder builder = RestClient.builder(new HttpHost(HTTP_HOST, PORT))
            .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
                @Override
                public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
                    return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
                }
            });
    // RestHighLevelClient实例通过REST low-level client builder进行构造。
    return new RestHighLevelClient(builder);
}

/**
 * 查询全部
 **/
@Test
public void testMatchAllQuery() {
    RestHighLevelClient highClient = getHighClient();
    try {
        //创建搜索请求对象
        SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
        //指定搜索类型
        searchRequest.types(TYPE_NAME);
        //搜索源构建对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //搜索方式
        //matchAllQuery搜索全部
        searchSourceBuilder.query(QueryBuilders.matchAllQuery());
        //设置源字段过虑,第一个参数结果集包括哪些字段,第二个参数表示结果集不包括哪些字段
        searchSourceBuilder.fetchSource(new String[]{"name", "age","description"}, new String[]{});
        //向搜索请求对象中设置搜索源
        searchRequest.source(searchSourceBuilder);
        //执行搜索,向ES发起http请求
        SearchResponse searchResponse = highClient.search(searchRequest,COMMON_OPTIONS);
        //搜索结果命中的记录
        SearchHits hits = searchResponse.getHits();
        //匹配到的总记录数
        long totalHits = hits.getTotalHits();
        System.out.println("匹配总记录数:" + totalHits);
        SearchHit[] searchHits = hits.getHits();
        for (SearchHit hit : searchHits) {
            //文档的主键
            String id = hit.getId();
            //源文档内容
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            String name = (String) sourceAsMap.get("name");
            String age = (String) sourceAsMap.get("age");
            System.out.println("name:" + name + ",age:" + age);
        }
        highClient.close();

    } catch (IOException ioException) {
        // 异常处理。
        System.out.println(ioException);
    }
}

3、查询全部并排序

@Test
public void testMatchAllQueryAndSort() {
    RestHighLevelClient highClient = getHighClient();
    try {
        //创建搜索请求对象
        SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
        //指定搜索类型
        searchRequest.types(TYPE_NAME);
        //搜索源构建对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //搜索方式
        //matchAllQuery搜索全部
        searchSourceBuilder.query(QueryBuilders.matchAllQuery());
        //设置源字段过虑,第一个参数结果集包括哪些字段,第二个参数表示结果集不包括哪些字段
        searchSourceBuilder.fetchSource(new String[]{"name", "age"}, new String[]{});

        //添加排序
        searchSourceBuilder.sort("age", SortOrder.DESC);
		//searchSourceBuilder.sort("age", SortOrder.ASC);

        //向搜索请求对象中设置搜索源
        searchRequest.source(searchSourceBuilder);
        //执行搜索,向ES发起http请求
        SearchResponse searchResponse = highClient.search(searchRequest,COMMON_OPTIONS);
        //搜索结果命中的记录
        SearchHits hits = searchResponse.getHits();
        //匹配到的总记录数
        long totalHits = hits.getTotalHits();
        System.out.println("匹配总记录数:" + totalHits);
        SearchHit[] searchHits = hits.getHits();
        for (SearchHit hit : searchHits) {
            //文档的主键
            String id = hit.getId();
            //源文档内容
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            String name = (String) sourceAsMap.get("name");
            String age = (String) sourceAsMap.get("age");
            System.out.println("name:" + name + ",age:" + age);
        }
        highClient.close();

    } catch (IOException ioException) {
        // 异常处理。
        System.out.println(ioException);
    }
}

4、分页查询

@Test
public void testPagingQuery() {
    RestHighLevelClient highClient = getHighClient();
    try {
        //搜索请求对象
        SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
        //指定类型
        searchRequest.types(TYPE_NAME);
        //搜索源构建对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //设置分页参数
        //页码
        int page = 1;
        //每页记录数
        int size = 1;
        //计算出记录起始下标
        int from = (page - 1) * size;
        searchSourceBuilder.from(from);//起始记录下标,从0开始
        searchSourceBuilder.size(size);//每页显示的记录数
        //搜索方式
        //matchAllQuery搜索全部
        searchSourceBuilder.query(QueryBuilders.matchAllQuery());
        //设置源字段过虑,第一个参数结果集包括哪些字段,第二个参数表示结果集不包括哪些字段
        searchSourceBuilder.fetchSource(new String[]{"name"}, new String[]{"age"});
        //向搜索请求对象中设置搜索源
        searchRequest.source(searchSourceBuilder);
        //执行搜索,向ES发起http请求
        SearchResponse searchResponse = highClient.search(searchRequest,COMMON_OPTIONS);
        //搜索结果
        SearchHits hits = searchResponse.getHits();
        //匹配到的总记录数
        long totalHits = hits.getTotalHits();
        System.out.println("总记录数:" + totalHits);
        //得到匹配度高的文档
        SearchHit[] searchHits = hits.getHits();
        for (SearchHit hit : searchHits) {
            String id = hit.getId();
            //源文档内容
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            String name = (String) sourceAsMap.get("name");
            String age = (String) sourceAsMap.get("age");
            //由于前边设置了源文档字段过虑,这时age是取不到的
            System.out.println("name:" + name + ",age:" + age);
        }
        highClient.close();
    } catch (IOException ioException) {
        // 异常处理。
        System.out.println(ioException);
    }
}

5、TermQuery查询

@Test
public void testTermQuery() {
    RestHighLevelClient highClient = getHighClient();
    try {
        //搜索请求对象
        SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
        //指定类型
        searchRequest.types(TYPE_NAME);
        //搜索源构建对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //搜索方式
        searchSourceBuilder.query(QueryBuilders.termQuery("name", "李四"));
        //设置源字段过虑,第一个参数结果集包括哪些字段,第二个参数表示结果集不包括哪些字段
        searchSourceBuilder.fetchSource(new String[]{"name", "age"}, new String[]{"description"});
        //向搜索请求对象中设置搜索源
        searchRequest.source(searchSourceBuilder);
        //执行搜索,向ES发起http请求
        SearchResponse searchResponse = highClient.search(searchRequest,COMMON_OPTIONS);
        //搜索结果
        SearchHits hits = searchResponse.getHits();
        //匹配到的总记录数
        long totalHits = hits.getTotalHits();
        System.out.println("总记录数:" + totalHits);
        //得到匹配度高的文档
        SearchHit[] searchHits = hits.getHits();
        for (SearchHit hit : searchHits) {
            //文档的主键
            String id = hit.getId();
            //源文档内容
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            String name = (String) sourceAsMap.get("name");
            //由于前边设置了源文档字段过虑,这时description是取不到的
            String description = (String) sourceAsMap.get("description");
            String age = (String) sourceAsMap.get("age");
            System.out.println("name:" + name + ",age:" + age + ",description:" + description);
        }
        highClient.close();
    } catch (IOException ioException) {
        // 异常处理。
        System.out.println(ioException);
    }
}

6、根据ids精确查询

@Test
public void testTermQueryByIds() {
    RestHighLevelClient highClient = getHighClient();
    try {
        //搜索请求对象
        SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
        //指定类型
        searchRequest.types(TYPE_NAME);
        //搜索源构建对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //定义id
        String[] ids = new String[]{"1", "2"};
        searchSourceBuilder.query(QueryBuilders.termsQuery("_id", ids));
        //设置源字段过虑,第一个参数结果集包括哪些字段,第二个参数表示结果集不包括哪些字段
        searchSourceBuilder.fetchSource(new String[]{"name", "age", "description"}, new String[]{});
        //向搜索请求对象中设置搜索源
        searchRequest.source(searchSourceBuilder);
        //执行搜索,向ES发起http请求
        SearchResponse searchResponse = highClient.search(searchRequest,COMMON_OPTIONS);
        //搜索结果
        SearchHits hits = searchResponse.getHits();
        //匹配到的总记录数
        long totalHits = hits.getTotalHits();
        //得到匹配度高的文档
        SearchHit[] searchHits = hits.getHits();
        for (SearchHit hit : searchHits) {
            //文档的主键
            String id = hit.getId();
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            String name = (String) sourceAsMap.get("name");
            String age = (String) sourceAsMap.get("age");
            String description = (String) sourceAsMap.get("description");
            System.out.println("name:" + name + ",age:" + age + ",description:" + description);
        }
        highClient.close();
    } catch (IOException ioException) {
        // 异常处理。
        System.out.println(ioException);
    }
}

7、MatchQuery

@Test
public void testMatchQuery() {
    RestHighLevelClient highClient = getHighClient();
    try {
        //搜索请求对象
        SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
        //指定类型
        searchRequest.types(TYPE_NAME);
        //搜索源构建对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        //搜索方式1:MatchQuery
		// searchSourceBuilder.query(QueryBuilders.matchQuery("description", "样样精通")
		//                    .minimumShouldMatch("80%"));


       //搜索方式2:MultiMatchQuery
        searchSourceBuilder.query(QueryBuilders.multiMatchQuery("李四是一个工程师", "name", "description")
                .minimumShouldMatch("50%")
                .field("name", 10));//权重提升10倍


        //设置源字段过虑,第一个参数结果集包括哪些字段,第二个参数表示结果集不包括哪些字段
        searchSourceBuilder.fetchSource(new String[]{"name", "age", "description"}, new String[]{});
        //向搜索请求对象中设置搜索源
        searchRequest.source(searchSourceBuilder);
        //执行搜索,向ES发起http请求
        SearchResponse searchResponse = highClient.search(searchRequest,COMMON_OPTIONS);
        //搜索结果
        SearchHits hits = searchResponse.getHits();
        //匹配到的总记录数
        long totalHits = hits.getTotalHits();
        //得到匹配度高的文档
        SearchHit[] searchHits = hits.getHits();
        for (SearchHit hit : searchHits) {
            //文档的主键
            String id = hit.getId();
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            String name = (String) sourceAsMap.get("name");
            String description = (String) sourceAsMap.get("description");
            String age = (String) sourceAsMap.get("age");
            System.out.println("ID:" + id + "name:" + name + ",age:" + age + ",description:" + description);

        }
        highClient.close();
    } catch (IOException ioException) {
        // 异常处理。
        System.out.println(ioException);
    }
}

8、BoolQuery搜索方式

@Test
public void testBoolQuery() {
    RestHighLevelClient highClient = getHighClient();
    try {
        //搜索请求对象
        SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
        //指定类型
        searchRequest.types(TYPE_NAME);
        //搜索源构建对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        //boolQuery搜索方式
        //先定义一个MultiMatchQuery
        MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery("李四", "name", "description")
                .minimumShouldMatch("50%")
                .field("name", 10);
        //再定义一个termQuery
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("age", "22");

        //定义一个boolQuery,必须满足两个条件
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(multiMatchQueryBuilder);
        boolQueryBuilder.must(termQueryBuilder);

        searchSourceBuilder.query(boolQueryBuilder);

        //设置源字段过虑,第一个参数结果集包括哪些字段,第二个参数表示结果集不包括哪些字段
        searchSourceBuilder.fetchSource(new String[]{"name", "age", "description"}, new String[]{});
        //向搜索请求对象中设置搜索源
        searchRequest.source(searchSourceBuilder);
        //执行搜索,向ES发起http请求
        SearchResponse searchResponse = highClient.search(searchRequest,COMMON_OPTIONS);
        //搜索结果
        SearchHits hits = searchResponse.getHits();
        //匹配到的总记录数
        long totalHits = hits.getTotalHits();
        System.out.println("总记录数:"+totalHits);
        //得到匹配度高的文档
        SearchHit[] searchHits = hits.getHits();
        for (SearchHit hit : searchHits) {
            //文档的主键
            String id = hit.getId();
            //源文档内容
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            String name = (String) sourceAsMap.get("name");
            String description = (String) sourceAsMap.get("description");
            String age = (String) sourceAsMap.get("age");
            System.out.println("ID:" + id + "name:" + name + ",age:" + age + ",description:" + description);
        }
        highClient.close();
    } catch (IOException ioException) {
        // 异常处理。
        System.out.println(ioException);
    }
}

9、Filter搜索方式/sort搜索方式

@Test
public void testFilter() {
    RestHighLevelClient highClient = getHighClient();
    try {
        //搜索请求对象
        SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
        //指定类型
        searchRequest.types(TYPE_NAME);
        //搜索源构建对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        //boolQuery搜索方式
        //先定义一个MultiMatchQuery
        MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery("李四是一个伟大的工程师", "name", "description")
                .minimumShouldMatch("50%")
                .field("name", 10);

        //定义一个boolQuery
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(multiMatchQueryBuilder);
        //定义过虑器
        boolQueryBuilder.filter(QueryBuilders.termQuery("name", "李四"));//不再分次,精确匹配查询
        boolQueryBuilder.filter(QueryBuilders.rangeQuery("age").gte(21).lte(30));//范围查询
        searchSourceBuilder.query(boolQueryBuilder);

        //设置源字段过虑,第一个参数结果集包括哪些字段,第二个参数表示结果集不包括哪些字段
        searchSourceBuilder.fetchSource(new String[]{"name", "age", "description"}, new String[]{});
        //向搜索请求对象中设置搜索源
        searchRequest.source(searchSourceBuilder);
        //执行搜索,向ES发起http请求
        SearchResponse searchResponse = highClient.search(searchRequest,COMMON_OPTIONS);
        //搜索结果
        SearchHits hits = searchResponse.getHits();
        //匹配到的总记录数
        long totalHits = hits.getTotalHits();
        //得到匹配度高的文档
        SearchHit[] searchHits = hits.getHits();
        for (SearchHit hit : searchHits) {
            //文档的主键
            String id = hit.getId();
            //源文档内容
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            String name = (String) sourceAsMap.get("name");
            String description = (String) sourceAsMap.get("description");
            String age = (String) sourceAsMap.get("age");
            System.out.println("ID:" + id + "name:" + name + ",age:" + age + ",description:" + description);
        }
        highClient.close();
    } catch (IOException ioException) {
        // 异常处理。
        System.out.println(ioException);
    }
}

10、Highlight高亮搜索

@Test
public void testHighlight() {
    RestHighLevelClient highClient = getHighClient();
    try {
        //搜索请求对象
        SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
        //指定类型
        searchRequest.types(TYPE_NAME);
        //搜索源构建对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //boolQuery搜索方式
        //先定义一个MultiMatchQuery
        MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery("李四是一个伟大的工程师", "name", "description")
                .minimumShouldMatch("50%")
                .field("name", 10);
        //定义一个boolQuery
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(multiMatchQueryBuilder);
        //定义过虑器
        boolQueryBuilder.filter(QueryBuilders.rangeQuery("age").gte(0).lte(30));

        searchSourceBuilder.query(boolQueryBuilder);
        //设置源字段过虑,第一个参数结果集包括哪些字段,第二个参数表示结果集不包括哪些字段
        searchSourceBuilder.fetchSource(new String[]{"name", "age","description"}, new String[]{});

        //设置高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.preTags("<tag>");
        highlightBuilder.postTags("</tag>");
        highlightBuilder.fields().add(new HighlightBuilder.Field("name"));
        //highlightBuilder.fields().add(new HighlightBuilder.Field("description"));
        searchSourceBuilder.highlighter(highlightBuilder);
        //向搜索请求对象中设置搜索源
        searchRequest.source(searchSourceBuilder);
        //执行搜索,向ES发起http请求
        SearchResponse searchResponse = highClient.search(searchRequest,COMMON_OPTIONS);
        //搜索结果
        SearchHits hits = searchResponse.getHits();
        //匹配到的总记录数
        long totalHits = hits.getTotalHits();
        //得到匹配度高的文档
        SearchHit[] searchHits = hits.getHits();
        for (SearchHit hit : searchHits) {
            //文档的主键
            String id = hit.getId();
            //源文档内容
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            String name = (String) sourceAsMap.get("name");
            String description = (String) sourceAsMap.get("description");
            String age = (String) sourceAsMap.get("age");

            //取出高亮字段
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            if(highlightFields!=null){
                //取出name高亮字段
                HighlightField nameHighlightField = highlightFields.get("name");
                if(nameHighlightField!=null){
                    Text[] fragments = nameHighlightField.getFragments();
                    StringBuffer stringBuffer = new StringBuffer();
                    for(Text text:fragments){
                        stringBuffer.append(text);
                    }
                    name = stringBuffer.toString();
                }
            }
            System.out.println("ID:" + id + ",name:" + name + ",age:" + age + ",description:" + description);

        }
        highClient.close();
    } catch (IOException ioException) {
        // 异常处理。
        System.out.println(ioException);
    }
  }
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Double@加贝

非常感谢家人们的打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值