文章目录

1. 环境准备1. 查询全部2. 根据 name 查询 match 分词查询3. 根据 name 和 品牌查询 multiMatch 分词查询4. 根据 brand 查询 match 分词查询5. 按照价格 范围查询6. 精确查询7. boolQuery8. 分页9. 高亮查询9. 公共解析

上一节讲述了 SpringBoot 实现 elasticsearch 索引操作,这一章节讲述 SpringBoot 实现 elasticsearch 查询操作。

1. 环境准备

案例用到的索引库结构

PUT /hotel

{

"mappings": {

"properties": {

"id": {

"type": "keyword"

},

"name":{

"type": "text",

"analyzer": "ik_max_word",

"copy_to": "all"

},

"address":{

"type": "keyword",

"index": false

},

"price":{

"type": "integer"

},

"score":{

"type": "integer"

},

"brand":{

"type": "keyword",

"copy_to": "all"

},

"city":{

"type": "keyword",

"copy_to": "all"

},

"starName":{

"type": "keyword"

},

"business":{

"type": "keyword"

},

"location":{

"type": "geo_point"

},

"pic":{

"type": "keyword",

"index": false

},

"all":{

"type": "text",

"analyzer": "ik_max_word"

}

}

}

}

1. 查询全部

@GetMapping("/searchAll")

public List searchAll() throws Exception {

//1.创建请求语义对象

SearchRequest searchRequest = new SearchRequest("索引名称");

// QueryBuilders: 构建查询类型

searchRequest.source().query(QueryBuilders.matchAllQuery());

SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

return handleResponse(searchResponse);

}

2. 根据 name 查询 match 分词查询

@GetMapping("/searchByName/{name}")

public List searchByName(@PathVariable("name") String name)

throws Exception {

//1.创建请求语义对象

SearchRequest searchRequest = new SearchRequest("索引名称");

// QueryBuilders: 构建查询类型

searchRequest.source().query(QueryBuilders.matchQuery("name", name));

SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

return handleResponse(searchResponse);

}

3. 根据 name 和 品牌查询 multiMatch 分词查询

@GetMapping("/searchByNameAndBrand/{name}")

public List searchByNameAndBrand(@PathVariable("name") String name) throws Exception {

//1.创建请求语义对象

SearchRequest searchRequest = new SearchRequest("索引名称");

// QueryBuilders: 构建查询类型

searchRequest.source().query(QueryBuilders.multiMatchQuery(name,"name","brand"));

SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

return handleResponse(searchResponse);

}

4. 根据 brand 查询 match 分词查询

@GetMapping("/searchByBrand/{name}")

public List searchByBrand(@PathVariable("name") String name) throws Exception {

//1.创建请求语义对象

SearchRequest searchRequest = new SearchRequest("索引名称");

// QueryBuilders: 构建查询类型

searchRequest.source().query(QueryBuilders.matchQuery("brand", name));

SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

return handleResponse(searchResponse);

}

5. 按照价格 范围查询

@GetMapping("/searchByPrice/{low}/{high}")

public List searchByPrice(@PathVariable("low") String low, @PathVariable("high") String high) throws Exception {

//1.创建请求语义对象

SearchRequest searchRequest = new SearchRequest("索引名称");

// QueryBuilders: 构建查询类型

searchRequest.source().query(QueryBuilders.rangeQuery("price").gte(low).lte(high));

SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

return handleResponse(searchResponse);

}

6. 精确查询

@GetMapping("/termQueryCity/{city}")

public List termQueryCity(@PathVariable("city") String city) throws Exception {

//1.创建请求语义对象

SearchRequest searchRequest = new SearchRequest("索引名称");

// QueryBuilders: 构建查询类型

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

//searchSourceBuilder.query(QueryBuilders.termQuery("city", city)); 这行有点小问题

// https://zhuanlan.zhihu.com/p/270426807 参考

searchSourceBuilder.query(QueryBuilders.termQuery("city.keyword", city));

searchRequest.source(searchSourceBuilder);

SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

return handleResponse(searchResponse);

}

7. boolQuery

@GetMapping("/testBool")

public List testBool() throws Exception {

// 1.准备Request

SearchRequest request = new SearchRequest("索引名称");

// 2.准备DSL

// 2.1.准备BooleanQuery

BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();

// 2.2.添加term

boolQuery.must(QueryBuilders.termQuery("city.keyword", "杭州"));

// 2.3.添加range

boolQuery.filter(QueryBuilders.rangeQuery("price").lte(250));

request.source().query(boolQuery);

// 3.发送请求

SearchResponse response = client.search(request, RequestOptions.DEFAULT);

// 4.解析响应

return handleResponse(response);

}

8. 分页

@GetMapping("/testPageAndSort/{currentPage}/{pageSize}")

public List testPageAndSort(@PathVariable("currentPage") Integer currentPage, @PathVariable("pageSize") Integer pageSize) throws Exception {

// 页码,每页大小

// 1.准备Request

SearchRequest request = new SearchRequest("索引名称");

// 2.准备DSL

// 2.1.query

request.source().query(QueryBuilders.matchAllQuery());

// 2.2.排序 sort

request.source().sort("price", SortOrder.ASC);

// 2.3.分页 from、size

request.source().from((currentPage - 1) * pageSize).size(pageSize);

// 3.发送请求

SearchResponse response = client.search(request, RequestOptions.DEFAULT);

// 4.解析响应

return handleResponse(response);

}

9. 高亮查询

@GetMapping("/testHighlight/{name}")

void testHighlight(@PathVariable("name") String name) throws Exception {

// 1.准备Request

SearchRequest request = new SearchRequest("索引名称");

// 2.准备DSL

// 2.1.query

request.source().query(QueryBuilders.matchQuery("name", name));

// 2.2.高亮

request.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false));

// 3.发送请求

SearchResponse response = client.search(request, RequestOptions.DEFAULT);

// 4.解析响应

handleResponse2(response);

}

9. 公共解析

private List handleResponse(SearchResponse response) throws Exception {

// 获取命中的所有内容

SearchHits searchHits = response.getHits();

// 获取命中的总条数

long count = searchHits.getTotalHits().value;

System.out.println("命中的条数为: "+ count);

// 获取命中的文档对象数组

SearchHit[] hits = searchHits.getHits();

List docList = new ArrayList<>();

for (SearchHit hit : hits) {

// 解析每一个hit对象得到对应的文档数据

String json = hit.getSourceAsString();

// HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);

docList.add(JSON.parseObject(json, HotelDoc.class));

}

//destroy();

return docList;

}

private void handleResponse2(SearchResponse response) {

// 4.解析响应

SearchHits searchHits = response.getHits();

// 4.1.获取总条数

long total = searchHits.getTotalHits().value;

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 highlightFields = hit.getHighlightFields();

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);

}

}

查看原文