Elasticsearch 部分基于流行度的评分结果

Elasticsearch score results based partly on Popularity

我正在为这个项目使用 Elasticsearch,但 Solr 解决方案可能也适用。在查询中,我想包含 should 子句的一部分,即使 none 其他术语可以,该子句也会 return 结果。这将用于文档流行度。我会定期计算阅读流行度,并为每个文档添加一个带有数值的浮点字段。

想法是 return 基于术语的文档,但如果失败,return 流行文档按受欢迎程度排名。这些应按术语匹配分数或受欢迎程度分数排序。

我意识到我可以量化流行度并将其视为标签 "hottest"、"hotter"、"hot"...但是我想使用数字字段,因为排名是定义明确。

这是我的数据的当前形式(通过 id 获取):

GET /index/docs/ipad

return一个示例对象

{
   "_index": "index",
   "_type": "docs",
   "_id": "doc1",
   "_version": 1,
   "found": true,
   "_source": {
      "category": ["tablets", "electronics"],
      "text": ["buy", "an",  "ipad"],
      "popularity": 0.95347457,
      "id": "doc1"
   }
}

当前查询格式

POST /index/docs/_search
{
   "size": 10,
   "query": {
      "bool": {
         "should": [
            {"terms": {"text": ["ipad"]}}
         ],
         "must": [
            {"terms": {"category": ["electronics"]}}
         ]
      }
   }
}

这可能看起来是一种奇怪的查询格式,但它们是结构化对象,而不是自由格式文本。

我能否向该查询添加流行度,以便它 return 的项目按流行程度与 return 由 should 项编辑的项目一起排名?我会将实际条款提高到受欢迎程度之上,这样他们就会受到青睐。

注意我不想靠人气来提升,我想return人气,如果剩下的查询return就没什么了。

您想查看 function score query 和衰减函数。

这是一个温和的介绍:https://www.found.no/foundation/function-scoring/

我能想到的一种方法是包装 match_all filter in constant score 并在分数上使用排序,然后是受欢迎程度

示例:

    {
   "size": 10,
   "query": {
      "bool": {
         "should": [
            {
               "terms": {
                  "text": [
                     "ipad"
                  ]
               }
            },
            {
               "constant_score": {
                  "filter": {
                     "match_all": {}
                  },
                  "boost": 0
               }
            }
         ],
         "must": [
            {
               "terms": {
                  "category": [
                     "electronics"
                  ]
               }
            }
         ],
         "minimum_should_match": 1
      }
   },
   "sort": [
      {
         "_score": {
            "order": "desc"
         }
      },
      {
         "popularity": {
            "unmapped_type": "double"
         }
      }
   ]
}