业务简述
有一批poi数据,需要根据给定地名首拼返回地点。例如给定wt 需要返回包括外滩相关的地名。
数据全部放在es中,且地名已经提取了首拼并存为字段
实现
指定了boost查询权重,但是发现使用spring-data-elasticsearch框架查询出来的结果跟我直接将查询DSL贴到kibana的结果并不一样。
同样的DSL语言在kibana是按照 score排序的,但是代码中的输出确没有排序。
代码中我是这么写的:
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(
boolQuery()
.should(boolQuery()
.must(queryStringQuery("*地名*").defaultField("type").boost(8))
.must(queryStringQuery(pinyin).defaultField("name_pinyin")))
.should(boolQuery()
.must(queryStringQuery("*公园*").defaultField("type").boost(10))
.must(queryStringQuery(pinyin).defaultField("name_pinyin")))
.should(boolQuery()
.must(queryStringQuery("*广场*").defaultField("type").boost(10))
.must(queryStringQuery(pinyin).defaultField("name_pinyin")))
.should(boolQuery()
.must(queryStringQuery("*风景名胜*").defaultField("type").boost(10))
.must(queryStringQuery(pinyin).defaultField("name_pinyin")))
.should(boolQuery()
.must(queryStringQuery("*交通*").defaultField("type").boost(5))
.must(queryStringQuery(pinyin).defaultField("name_pinyin")))
.should(boolQuery()
.must(queryStringQuery("*餐厅*").defaultField("type").boost(3))
.must(queryStringQuery(pinyin).defaultField("name_pinyin")))
)
.withPageable(PageRequest.of(0, 100)).withSort(SortBuilders.scoreSort()).build();
一样的DSL但是一个按照score排序,一个没有排序,那么肯定肯定不是DSL语言的问题,应该是是代码中使用的排序方式错了。找了半天,最后找到是调用的方式不对,想要 按照score 排序,那么需要使用 functionScoreQuery,最终代码是
FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery(
QueryBuilders.boolQuery()
.should(boolQuery()
.must(queryStringQuery("*地名*").defaultField("type").boost(8))
.must(queryStringQuery(pinyin).defaultField("name_pinyin")))
.should(boolQuery()
.must(queryStringQuery("*公园*").defaultField("type").boost(10))
.must(queryStringQuery(pinyin).defaultField("name_pinyin")))
.should(boolQuery()
.must(queryStringQuery("*广场*").defaultField("type").boost(10))
.must(queryStringQuery(pinyin).defaultField("name_pinyin")))
.should(boolQuery()
.must(queryStringQuery("*风景名胜*").defaultField("type").boost(10))
.must(queryStringQuery(pinyin).defaultField("name_pinyin")))
.should(boolQuery()
.must(queryStringQuery("*交通*").defaultField("type").boost(5))
.must(queryStringQuery(pinyin).defaultField("name_pinyin")))
.should(boolQuery()
.must(queryStringQuery("*餐厅*").defaultField("type").boost(3))
.must(queryStringQuery(pinyin).defaultField("name_pinyin")))
);
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(functionScoreQueryBuilder)
.withPageable(PageRequest.of(0, 10)).withSort(SortBuilders.scoreSort()).build();
这样调用,查询的结果跟在kibana完全一致