目录
1、DSL查询语法
常见的查询类型包括:
- 查询所有:查询出所有数据,一般测试用。例如:match_all
- 全文检索(full text)查询:利用分词器对用户输入内容分词,然后去倒排索引库中匹配。例如:
- match_query
- multi_match_query
- 精确查询:根据精确词条值查找数据,一般是查找keyword、数值、日期、boolean等类型字段。例如:
- ids
- range:根据值的范围查询
- term:根据词条精确值查询
- 地理(geo)查询:根据经纬度查询。例如:
- geo_distance:查询到指定中心点小于某个距离值的所有文档
- geo_bounding_box:查询geo_point值落在某个矩形范围的所有文档
- 复合(compound)查询:复合查询可以将上述各种查询条件组合起来,合并查询条件。例如:
- bool
- function_score:算分函数查询,可以控制文档相关性算分,控制文档排名。例如百度竞价
使用 function score query,可以修改文档的相关性算分(query score),根据新得到的算分排序。
2、搜索结果处理
1、排序
elasticsearch支持对搜索结果排序,默认是根据相关度算分(_score)来排序。可以排序字段类型有:keyword类型、数值类型、地理坐标类型、日期类型等。
2、分页
elasticsearch 默认情况下只返回top10的数据。而如果要查询更多数据就需要修改分页参数了。
elasticsearch中通过修改from、size参数来控制要返回的分页结果:
针对深度分页,ES提供了两种解决方案:
- search after:分页时需要排序,原理是从上一次的排序值开始,查询下一页数据。官方推荐使用的方式。
- scroll:原理将排序数据形成快照,保存在内存。官方已经不推荐使用。
3、高亮
就是在搜索结果中把搜索关键字突出显示。
原理是这样的:
- 将搜索结果中的关键字用标签标记出来
- 在页面中给标签添加css样式
3、RestClient实现
@Test
void test1() throws IOException {
SearchRequest request = new SearchRequest("hotel");
request.source().query(QueryBuilders.matchAllQuery());
SearchResponse search = client.search(request, RequestOptions.DEFAULT);
SearchHits searchHits = search.getHits();
//获取总数
long value = searchHits.getTotalHits().value;
System.err.println("共搜索到:"+value+" 条数据");
//文档数组
SearchHit[] hits = searchHits.getHits();
for(SearchHit hit : hits){
//获得文档source——具体数据
String json = hit.getSourceAsString();
HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
System.out.println(hotelDoc);
}
}
全文检索查询:
精确查询:
复合查询:
BoolQueryBuilder builder = QueryBuilders.boolQuery();
builder.must(QueryBuilders.termQuery("city","上海"));
builder.filter(QueryBuilders.rangeQuery("price").lte(250));
request.source().query(builder);
排序和分页:
int page = 1;
int size = 5;
SearchRequest request = new SearchRequest("hotel");
request.source().query(QueryBuilders.matchAllQuery());
request.source().sort("price", SortOrder.ASC);
request.source().from((page-1)*size).size(size);
高亮:
request.source().query(QueryBuilders.matchQuery("all","如家"));
request.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false));
//获取高亮结果
Map<String, HighlightField> fieldMap = hit.getHighlightFields();
if(!CollectionUtils.isEmpty(fieldMap)){
HighlightField field = fieldMap.get("name");
if(field != null){
//获取高亮值
String name = field.getFragments()[0].string();
hotelDoc.setName(name);
}
}