ElasticSearch的复杂查询

1,411 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

近期在工作中需要使用es进行简单的全文检索,所以最近都在边学边做笔记,也会把自己遇到的bug以及如何解决的,一并记录在这里,供大家学习参考。

条件查询

term查找单值精确查询,使用精确查询的时候字段不能使用分词
terms查找多值精确查询,类似于sql中in的查询

image.png

分页查询

分页查询可使用query.withPageable()方法进行设置,简单又高效哦!!!

NativeSearchQueryBuilder query = new NativeSearchQueryBuilder();
//分页
//req.getPageNum():第几页
//req.getPageSize():每页显示多少条
Pageable pageable = PageRequest.of(1, 2);
query.withPageable(pageable);

总共有三条数据,这样就会只显示前两条。 image.png 相当于这种搜索语句:

"from":1,
"size":2

查询排序

es的排序同sql,指定排序字段和排序方式。排序可以选择query.sort()方法。

@Test
void sort(){
    NativeSearchQueryBuilder query = new NativeSearchQueryBuilder();
    query.withSort(SortBuilders.fieldSort("age").order(SortOrder.DESC));
    SearchHits<User> hits = elasticsearchRestTemplate.search(query.build(),User.class);
    for (SearchHit<User> user:hits) {
        System.out.println(user.getContent().toString());
    }
}

结果展示: image.png 相当于这种搜索语句:

"sort": [
{
    "age": {
        "order": "desc"
     }
}
]

支持多字段排序,排序的字段不支持分词。

过滤

使用filter与boo进行复杂的多条件查询

在bool嵌套查询中,我们可以使用boolQueryBuilder.filter()对搜索内容进行过滤。 对于age这种int类型和date时间类型可以使用QueryBuilders.rangeQuery("age")

.gte(1).lte(20)表示大于等于1小于等于20

.from(beginTime).to(endTime)表示某一时间段内的数据

QueryBuilders.matchQuery("sex", "女").operator(Operator.AND)这个就是使用match精确查找的方式进行过滤

BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
List<QueryBuilder> filters = boolQueryBuilder.filter();
filters.add(QueryBuilders.rangeQuery("age").gte(18).lte(45));
filters.add(QueryBuilders.rangeQuery("date").from(beginTime).to(endTime));
filters.add(QueryBuilders.matchQuery("sex", param.getSex()).operator(Operator.AND));

与must查询相比,filter查询不计算评分,查询效率高,有缓存