如何通过score + boost + field对弹性搜索结果进行排序?

vre*_*sys 4 sorting lucene elasticsearch

给定具有标题,作者和描述的书籍索引,我希望以这种方式对得到的搜索结果进行排序:

  1. 所有符合标题的书籍按下载排序(数值)
  2. 所有与作者匹配的书籍按下载排序
  3. 所有符合描述的书籍按下载排序

我使用下面的搜索查询,但问题是每个条目都有不同的分数,因此按下载排序无关紧要.

例如,当搜索词是'排序'时 - 标题:'弹性搜索中的排序'将得分高于标题:'postgresql排序很棒'(因为单词位置).

query = QueryBuilders.multiMatchQuery(queryString, "title^16", "author^8", "description^4")

elasticClient.prepareSearch(Index)
      .setTypes(Book)          
      .setQuery(query)
      .addSort(SortBuilders.scoreSort())
      .addSort(SortBuilders.fieldSort("downloads").order(SortOrder.DESC))
Run Code Online (Sandbox Code Playgroud)

如何构建我的查询,以便我可以获得所需的书籍排序?

我使用标准分析器,我需要分析搜索查询,我还要处理多字搜索查询字符串.

谢谢.

Vin*_*han 7

您需要的是一种基于三个加权字段和数字字段计算分数的方法.排序将对从两者获得的分数求和,由此,如果其中任何一个太大,它将取代另一个.因此,更好的方法是通过匹配获得的分数进行多次下载.所以我会推荐功能评分查询 -

{
  "query": {
    "function_score": {
      "query": {
        "multi_match": {
          "query": "sorting",
          "fields": [
            "title^16",
            "author^8",
            "description^4"
          ]
        }
      },
      "function": [
        {
          "field_value_factor": {
            "field": "downloads"
          }
        }
      ],
      "boost_mode": "multiply"
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

这将根据所有三个字段计算得分.然后将该分数乘以下载字段中的值以获得最终分数.乘法boost_mode决定函数计算的值如何与查询计算的分数一起分组.