關於Elasticsearch查詢按照相關性排序的問題

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完全一致

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章