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

时间:2014-12-30 09:41:32

标签: sorting elasticsearch lucene

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

  1. 所有符合标题的书籍按下载顺序排列(数值)
  2. 所有与作者相匹配的书籍按下载排序
  3. 所有符合说明的书籍按下载排序
  4. 我使用下面的搜索查询,但问题是每个条目都有不同的分数,因此按下载排序无关紧要。

    e.g。当搜索词是'排序' - 标题:'在弹性搜索中排序'得分高于标题:' 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))
    

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

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

    THX。

1 个答案:

答案 0 :(得分: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"
    }
  }
}

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