spring elasticsearch 查結果按照score降序輸出
業務簡述
有一批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完全一致