RestClient查询文档
前面我们已经实现利用DSL实现文档查询和后续结果处理,下面我们利用Java RestClient实现前面的功能
一、快速入门
1.1.基本案例演示
我们通过match_all来演示下基本的APl,先看请求DSL的组织:查询所有的信息如下:
@SpringBootTest public class HotelSearchTests { //创建成员变量,保存初始化的对象 private RestHighLevelClient client; @BeforeEach void setUp(){ this.client = new RestHighLevelClient( RestClient.builder(HttpHost.create("http://192.168.42.150:9200") )); } @AfterEach void testDown() throws IOException { this.client.close(); } /** * 查询所有的数据 * @throws IOException */ @Test void testMatchAll() throws IOException { //1.准备request SearchRequest request = new SearchRequest("hotel"); //2.准备DSL request.source().query(QueryBuilders.matchAllQuery()); //3.发送请求 SearchResponse response = client.search(request, RequestOptions.DEFAULT); System.out.println(response); } }
执行后结果如下:

1.2.结果解析
上面的操作完成后,我们需要对于返回的结果进行解析,通过解析拿出我们需要的信息:

代码如下:
/** * 查询所有的数据 * @throws IOException */ @Test void testMatchAll() throws IOException { //1.准备request SearchRequest request = new SearchRequest("hotel"); //2.准备DSL request.source().query(QueryBuilders.matchAllQuery()); //3.发送请求 SearchResponse response = client.search(request, RequestOptions.DEFAULT); //4.解析结果 SearchHits searchHits = response.getHits(); //4.1.查询总条数 long total = searchHits.getTotalHits().value; System.out.println("共搜索到:"+total+"条数据"); //4.2.查询的结果数组 for (SearchHit hit : searchHits.getHits()) { //4.3.获取文档source String json = hit.getSourceAsString(); //4.4.打印输出 System.out.println(json); //4.5.反序列化 HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class); System.out.println("hotelDoc = "+hotelDoc); } }
执行后结果如下:

1.3.Query Builders的工具类
Rest API中其中构建查询条件的核心部分是由一个名为Query Builders的工具类提供的,其中包含了各种查询方法:

在 Elasticsearch Java 客户端中,Query Builders 提供了一系列用于构建查询的工具类。这些工具类通常位于 org.elasticsearch.index.query 包中。以下是一些常用的 Query Builders 工具类及其方法:
-
QueryBuilders.termQuery(String name, Object value):创建一个精确匹配的项查询。 -
QueryBuilders.matchQuery(String name, Object value):创建一个全文匹配查询。 -
QueryBuilders.boolQuery():创建一个布尔查询,用于组合多个查询条件。 -
QueryBuilders.rangeQuery(String name):创建一个范围查询,用于匹配指定范围内的值。 -
QueryBuilders.existsQuery(String name):创建一个存在性查询,用于匹配指定字段存在的文档。 -
QueryBuilders.prefixQuery(String name, String prefix):创建一个前缀查询,用于匹配指定前缀的项。
这些方法通常用于构建查询条件,并且可以与其他查询条件组合使用。在使用这些方法时,通常需要将返回的查询对象添加到查询构建器中,然后将构建器用于执行搜索操作。
二、match查询
2.1.语法说明
全文检索的match和multi_match查询与match_all的APl基本一致,差别是查询条件,也就是query的部分。语法如下:
//单字段查询 QueryBuilders.matchQuery("all","如家"); //多字段查询 QueryBuilders.multiMatchQuery("如家","name","business");
2.2.单字段查询
利用QueryBuilders.matchQuery("all","如家")完成单个字段查询
/** * 单字段查询 * @throws IOException */ @Test void testMatchQuery() throws IOException { //1.准备request SearchRequest request = new SearchRequest("hotel"); //2.准备DSL request.source().query(QueryBuilders.matchQuery("all","如家")); //3.发送请求 SearchResponse response = client.search(request, RequestOptions.DEFAULT); //4.解析结果 SearchHits searchHits = response.getHits(); //4.1.查询总条数 long total = searchHits.getTotalHits().value; System.out.println("共搜索到:"+total+"条数据"); //4.2.查询的结果数组 for (SearchHit hit : searchHits.getHits()) { //4.3.获取文档source String json = hit.getSourceAsString(); //4.4.打印输出 System.out.println(json); //4.5.反序列化 HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class); System.out.println("hotelDoc = "+hotelDoc); } }
执行后结果如下:

解析结果的代码是重复的代码,我们可以把它抽取出来,如下:
/** * 单字段查询 * @throws IOException */ @Test void testMatchQuery() throws IOException { //1.准备request SearchRequest request = new SearchRequest("hotel"); //2.准备DSL request.source().query(QueryBuilders.matchQuery("all","如家")); //3.发送请求 SearchResponse response = client.search(request, RequestOptions.DEFAULT); //调用方法解析结构 handleResponse(response); } private void handleResponse(SearchResponse response){ //4.解析结果 SearchHits searchHits = response.getHits(); //4.1.查询总条数 long total = searchHits.getTotalHits().value; System.out.println("共搜索到:"+total+"条数据"); //4.2.查询的结果数组 for (SearchHit hit : searchHits.getHits()) { //4.3.获取文档source String json = hit.getSourceAsString(); //4.4.打印输出 System.out.println(json); //4.5.反序列化 HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class); System.out.println("hotelDoc = "+hotelDoc); } }
2.2.多字段查询
多字段查询利用,QueryBuilders.multiMatchQuery("如家","name","business");完成
/** * 多字段查询 * @throws IOException */ @Test void testMultiMatchQuery() throws IOException { //1.准备request SearchRequest request = new SearchRequest("hotel"); //2.准备DSL request.source().query(QueryBuilders.multiMatchQuery("如家", "name", "business")); //3.发送请求 SearchResponse response = client.search(request, RequestOptions.DEFAULT); //调用方法解析结构 handleResponse(response); }
三、精确查询
3.1.语法说明
精确查询常见的有term查询和range查询,同样利用QueryBuilders实现,语法如下:
//词条查询 QueryBuilders.termQuery("city","杭州"); //范围查询 QueryBuilders.rangeQuery("price").gte(100).lte(150);
3.2.精确查询:词条查询
案例如下:
@Test void testTermQuery() throws IOException { //1.准备request SearchRequest request = new SearchRequest("hotel"); //2.准备DSL request.source().query(QueryBuilders.termQuery("city","上海")); //3.发送请求 SearchResponse response = client.search(request, RequestOptions.DEFAULT); //解析结构 handleResponse(response); }
3.3.精确查询:范围查询
案例如下:查询价格在100到200之间的酒店信息
@Test void testRangeQuery() throws IOException { //1.准备request SearchRequest request = new SearchRequest("hotel"); //2.准备DSL request.source().query(QueryBuilders.rangeQuery("price").gte(100).lte(200)); //3.发送请求 SearchResponse response = client.search(request, RequestOptions.DEFAULT); //解析结构 handleResponse(response); }
执行后结果如下:

四、复合查询
4.1.语法说明
复合查询,也就是组合查询,利用精确查询常见的有term查询和range查询,同样利用Query Builders实现:
//创建布尔查询 BoolQueryBuilder boolQuery=QueryBuilders.boolQuery(); //添加must条件 boolQuery.must(QueryBuilders.term Query("city","杭州")); //添加filter条件 boolQuery.filter(QueryBuilders.range Query("price").lte(250));
4.2.案例
代码如下:
@Test void testBool() throws IOException { //1.准备request SearchRequest request = new SearchRequest("hotel"); //2.准备DSL //2.1.准备BooleanQuery BoolQueryBuilder boolQuery = QueryBuilders.boolQuery(); //2.2.添加term boolQuery.must(QueryBuilders.termQuery("city", "上海")); //2.3.添加range 价格小于等于400的 boolQuery.filter(QueryBuilders.rangeQuery("price").lte(400)); request.source().query(boolQuery); //3.发送请求 SearchResponse response = client.search(request, RequestOptions.DEFAULT); //解析结构 handleResponse(response); }
执行后如下:

五、排序、分页、高亮
5.1.排序和分页
搜索结果的排序和分页是与query同级的参数,对应的API如下:

代码如下:
@Test void testPageAndSort() throws IOException { //页码和每页大小 int page=1; int size=5; //1.准备request SearchRequest request = new SearchRequest("hotel"); //2.准备DSL //2.1.准备Query request.source().query(QueryBuilders.matchAllQuery()); //2.2.排序 request.source().sort("price", SortOrder.ASC); //2.3.分页 request.source().from((page-1)*size).size(size); //3.发送请求 SearchResponse response = client.search(request, RequestOptions.DEFAULT); //解析结构 handleResponse(response); }
执行后结果如下:

5.2.高亮
高亮API包括请求DSL和结果解析两部分
5.2.1.高亮请求DSL构建
语法如下:

代码如下:
@Test void testHighlight() throws IOException { //1.准备request SearchRequest request = new SearchRequest("hotel"); //2.准备DSL //2.1.准备Query request.source().query(QueryBuilders.matchQuery("all", "如家")); //2.2.高亮: 由于上面查询的拷贝字段all,下面高亮显示的指定的是name字段,不一致,则需设置requireFieldMatch(false) request.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false)); //3.发送请求 SearchResponse response = client.search(request, RequestOptions.DEFAULT); //解析结构 handleResponse(response); }
查看结果并没有高亮显示的部分,因为这里我们只是做了高亮的构建部分,结果解析部分还没有做,如下:

5.2.2.高亮结果解析
语法如下:

代码如下:
@Test void testHighlight() throws IOException { //1.准备request SearchRequest request = new SearchRequest("hotel"); //2.准备DSL //2.1.准备Query request.source().query(QueryBuilders.matchQuery("all", "如家")); //2.2.高亮: 由于上面查询的拷贝字段all,下面高亮显示的指定的是name字段,不一致,则需设置requireFieldMatch(false) request.source().highlighter( new HighlightBuilder() .field("name") .requireFieldMatch(false)); //3.发送请求 SearchResponse response = client.search(request, RequestOptions.DEFAULT); //4.解析响应 SearchHits searchHits = response.getHits(); //4.1.获取总条数 TotalHits total = searchHits.getTotalHits(); System.out.println("获取的消息的条数:"+total); //4.2.文档数组 SearchHit[] hits = searchHits.getHits(); //4.3.遍历 for (SearchHit hit : hits) { //获取文档source String json = hit.getSourceAsString(); //反序列化 HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class); //获取高亮结果 Map<String, HighlightField> highlightFields = hit.getHighlightFields(); //Spring给我们提供了一个工具类,为我们判断是否为空:CollectionUtils.isEmpty() if(!CollectionUtils.isEmpty(highlightFields)){ //根据字段名获取高亮结果 HighlightField highlightField = highlightFields.get("name"); if(highlightField != null){ //获取高亮的值 String name = highlightField.getFragments()[0].string(); //覆盖非高亮结果 hotelDoc.setName(name); } } System.out.println("hotelDoc = "+hotelDoc); } }
执行后结果如下:


浙公网安备 33010602011771号