分布式搜索引擎ElasticSearch——搜索功能
文章目录
- 分布式搜索引擎ElasticSearch——搜索功能
- DSL查询文档
- DSL查询分类
- 全文检索查询
- 精确查询
- 地理查询
- 复合查询
- Function Score Query
- Boolean Query
- 搜索结果处理
- 排序![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/37de45bd79be4316a9c23040f754758e.png)
- 分页
- 高亮
- RestClient查询文档
- 快速入门
- match,term,range,bool查询
- 排序和分页
- 高亮显示
- 黑马旅游案例
- 基本的搜索和分页
- 条件过滤
- 找周边的酒店
- 广告置顶
DSL查询文档
DSL查询分类
DSL官方文档
全文检索查询
精确查询
地理查询
复合查询
Function Score Query
function score query
Boolean Query
搜索结果处理
排序
分页
官方文档
高亮
RestClient查询文档
快速入门
public class HotelSearchTest {private RestHighLevelClient client;@Testvoid testMatchAll() throws IOException {// 1. 准备RequestSearchRequest request = new SearchRequest("hotel");// 2. 准备DSLrequest.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 文档数组SearchHit[] hits = searchHits.getHits();// 4.3 遍历for (SearchHit hit : hits) {// 获取文档sourceString json = hit.getSourceAsString();// 反序列化HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);System.out.println("hotelDoc = " + hotelDoc);}System.out.println(response);}@BeforeEachvoid setUp(){this.client = new RestHighLevelClient(RestClient.builder(HttpHost.create("http://192.168.10.88:9200")));}@AfterEachvoid tearDown() throws IOException {this.client.close();}
}
match,term,range,bool查询
// 全文检索查询@Testvoid testMatch() throws IOException {// 1. 准备RequestSearchRequest request = new SearchRequest("hotel");// 2. 准备DSLrequest.source().query(QueryBuilders.matchQuery("all","皇冠"));// 3. 发送请求SearchResponse response = client.search(request, RequestOptions.DEFAULT);handleResponse(response);System.out.println(response);}// bool查询@Testvoid testBool() throws IOException {// 1. 准备RequestSearchRequest request = new SearchRequest("hotel");// 2. 准备DSL// 2.1 准备BooleanQueryBoolQueryBuilder boolQuery = QueryBuilders.boolQuery();// 2.2 添加termboolQuery.must(QueryBuilders.termQuery("city","杭州"));// 2.3 添加rangeboolQuery.filter(QueryBuilders.rangeQuery("price").lte(250));request.source().query(boolQuery);// 3. 发送请求SearchResponse response = client.search(request, RequestOptions.DEFAULT);handleResponse(response);System.out.println(response);}// 抽取解析的代码private static void handleResponse(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) {// 获取文档sourceString json = hit.getSourceAsString();// 反序列化HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);System.out.println("hotelDoc = " + hotelDoc);}}
排序和分页
// 排序和分页@Testvoid testPageAndSort() throws IOException {// 页码。每页大小int page = 2, size = 5;// 1. 准备RequestSearchRequest request = new SearchRequest("hotel");// 2. 准备DSL// 2.1 queryrequest.source().query(QueryBuilders.matchAllQuery());// 2.2 配许sortrequest.source().sort("price", SortOrder.ASC);// 2.3 分页from, sizerequest.source().from((page-1)*size).size(5);// 3. 发送请求SearchResponse response = client.search(request, RequestOptions.DEFAULT);// 4. 解析响应handleResponse(response);}
高亮显示
// 高亮@Testvoid testHighlight() throws IOException {// 1. 准备RequestSearchRequest request = new SearchRequest("hotel");// 2. 准备DSL// 2.1 queryrequest.source().query(QueryBuilders.matchQuery("all","如家"));// 2.2 高亮request.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false));// 3. 发送请求SearchResponse response = client.search(request, RequestOptions.DEFAULT);// 4. 解析响应handleResponse(response);}
就是在前面抽取的解析代码中进一步添加关于高亮的解析部分,因为highlight和source是同级目录的,所以采用的方法类似。
// 抽取解析的代码private static void handleResponse(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) {// 获取文档sourceString json = hit.getSourceAsString();// 反序列化HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);// 获取高亮结果Map<String, HighlightField> 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);}}
黑马旅游案例
基本的搜索和分页
@RestController
@RequestMapping("/hotel")
public class HotelController {@Autowiredprivate IHotelService hotelService;@PostMapping("/list")public PageResult search(@RequestBody RequestParams params){return hotelService.search(params);}
}
@Service
public class HotelService extends ServiceImpl<HotelMapper, Hotel> implements IHotelService {@Autowiredprivate RestHighLevelClient client;@Overridepublic PageResult search(RequestParams params) {try {// 1. 准备RequestSearchRequest request = new SearchRequest("hotel");// 2. 准备DSL// 2.1 queryString key = params.getKey();if (key == null || "".equals(key)) {request.source().query(QueryBuilders.matchAllQuery());} else {request.source().query(QueryBuilders.matchQuery("all", key));}// 2.2 分页int page = params.getPage();int size = params.getSize();request.source().from((page - 1) * size).size(size);// 3. 发送请求SearchResponse response = client.search(request, RequestOptions.DEFAULT);// 4. 解析响应return handleResponse(response);}catch (IOException e){throw new RuntimeException(e);}}// 抽取解析的代码private PageResult handleResponse(SearchResponse response) {// 4. 解析响应SearchHits searchHits = response.getHits();// 4.1 获取总条数long total = searchHits.getTotalHits().value;// 4.2 文档数组SearchHit[] hits = searchHits.getHits();// 4.3 遍历List<HotelDoc> hotels = new ArrayList<>();for (SearchHit hit : hits) {// 获取文档sourceString json = hit.getSourceAsString();// 反序列化HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);hotels.add(hotelDoc);}// 4.4 封装返回return new PageResult(total,hotels);}}
条件过滤
@Overridepublic PageResult search(RequestParams params) {try {// 1. 准备RequestSearchRequest request = new SearchRequest("hotel");// 2. 准备DSL// 2.1 query// 构建BooleanQuerybuildBasicQuery(params, request);// 2.2 分页int page = params.getPage();int size = params.getSize();request.source().from((page - 1) * size).size(size);// 3. 发送请求SearchResponse response = client.search(request, RequestOptions.DEFAULT);// 4. 解析响应return handleResponse(response);}catch (IOException e){throw new RuntimeException(e);}}private static void buildBasicQuery(RequestParams params, SearchRequest request) {BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();// 关键字搜索String key = params.getKey();if (key == null || "".equals(key)) {boolQuery.must(QueryBuilders.matchAllQuery());} else {boolQuery.must(QueryBuilders.matchQuery("all", key));}// 条件过滤// 城市if(params.getCity() != null && !"".equals(params.getCity())){boolQuery.filter(QueryBuilders.termQuery("city", params.getCity()));}// 品牌if(params.getBrand() != null && !"".equals(params.getBrand())){boolQuery.filter(QueryBuilders.termQuery("brand", params.getBrand()));}// 星级if(params.getStarName() != null && !"".equals(params.getStarName())){boolQuery.filter(QueryBuilders.termQuery("starName", params.getStarName()));}// 价格——范围过滤if(params.getMinPrice() != null && params.getMaxPrice() != null){boolQuery.filter(QueryBuilders.rangeQuery("price").gte(params.getMinPrice()).lte(params.getMaxPrice()));}request.source().query(boolQuery);}
找周边的酒店
广告置顶
// 2. 算分控制FunctionScoreQueryBuilder functionScoreQuery =QueryBuilders.functionScoreQuery(// 原始查询,相关性算分的查询boolQuery,// function score的数组new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{// 其中的一个function score元素new FunctionScoreQueryBuilder.FilterFunctionBuilder(// 过滤条件QueryBuilders.termQuery("isAD",true),// 算分函数ScoreFunctionBuilders.weightFactorFunction(10))});