【问题标题】:Rank records on the basis of a field value in Elasticsearch根据 Elasticsearch 中的字段值对记录进行排名
【发布时间】:2021-05-30 20:58:00
【问题描述】:

我在记录架构中有一个字段 distribution,如下所示:

...
"distribution": {
    "properties": {
        "availability": {
            "type": "keyword"
         } 
     }
}
...

我想将distribution.availability == "ondemand" 的记录排名低于其他记录。

我查看了 Elasticsearch docs,但无法找到一种方法来降低此类记录在 index-time 内的分数以使其在搜索结果中显示得更低。

我怎样才能做到这一点,任何指向相关来源的指针也足够了。

更多信息:

我在 query-time 的 python 客户端的帮助下完全省略了这些 ondemand 记录,如下所示:

from elasticsearch_dsl.query import Q

_query = Q("query_string", query=query_string) & ~Q('match', **{'availability.keyword': 'ondemand'})

现在,我想包含这些记录,但我想将它们放置在低于其他记录的位置。

如果在 index-time 中无法实现类似的功能,请建议我如何使用 python 客户端在 query-time 中实现此功能。

应用 llermaly 的建议后,python 客户端查询如下所示:

boosting_query = Q(
    "boosting",
    positive=Q("match_all"),
    negative=Q(
        "bool", filter=[Q({"term": {"distribution.availability.keyword": "ondemand"}})]
    ),
    negative_boost=0.5,
)
if query_string:
    _query = Q("query_string", query=query_string) & boosting_query
else:
    _query = Q() & boosting_query

【问题讨论】:

    标签: python elasticsearch mapping ranking


    【解决方案1】:

    EDIT2 : elasticsearch-dsl-py 增强查询版本

    from elasticsearch import Elasticsearch
    from elasticsearch_dsl import Search
    from elasticsearch_dsl import Q
    
    client = Elasticsearch()
    q = Q('boosting', positive=Q("match_all"), negative=Q('bool', filter=[Q({"term": {"test.available.keyword": "ondemand"}})]), negative_boost=0.5)
    s = Search(using=client, index="test_parths007").query(q)
    
    response = s.execute()
    print(response)
    for hit in response:
        print(hit.meta.score, hit.test.available)
    

    编辑:只需阅读您需要在索引时间执行此操作。

    Elasticsearch 在 5.0 上弃用了索引时间提升 https://www.elastic.co/guide/en/elasticsearch/reference/7.11/mapping-boost.html

    您可以使用Boosting query 来实现查询时间。

    提取文档

    POST test_parths007/_doc
    {
      "name": "doc1",
      "test": {
        "available": "ondemand"
      }
    }
    
    POST test_parths007/_doc
    {
      "name": "doc1",
      "test": {
        "available": "higherscore"
      }
    }
    
    POST test_parths007/_doc
    {
      "name": "doc2",
      "test": {
        "available": "higherscore"
      }
    }
    

    查询(索引时间)

    POST test_parths007/_search
    {
      "query": {
        "boosting": {
          "positive": {
            "match_all": {}
          },
          "negative": {
            "term": {
              "test.available.keyword": "ondemand"
            }
          },
          "negative_boost": 0.5
        }
      }
    }
    

    回应

    {
      "took" : 0,
      "timed_out" : false,
      "_shards" : {
        "total" : 1,
        "successful" : 1,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : {
          "value" : 3,
          "relation" : "eq"
        },
        "max_score" : 1.0,
        "hits" : [
          {
            "_index" : "test_parths007",
            "_type" : "_doc",
            "_id" : "VMdY7XcB50NMsuQPelRx",
            "_score" : 1.0,
            "_source" : {
              "name" : "doc2",
              "test" : {
                "available" : "higherscore"
              }
            }
          },
          {
            "_index" : "test_parths007",
            "_type" : "_doc",
            "_id" : "Vcda7XcB50NMsuQPiVRB",
            "_score" : 1.0,
            "_source" : {
              "name" : "doc1",
              "test" : {
                "available" : "higherscore"
              }
            }
          },
          {
            "_index" : "test_parths007",
            "_type" : "_doc",
            "_id" : "U8dY7XcB50NMsuQPdlTo",
            "_score" : 0.5,
            "_source" : {
              "name" : "doc1",
              "test" : {
                "available" : "ondemand"
              }
            }
          }
        ]
      }
    }
    
    

    对于更高级的操作,您可以查看Function Score Query

    【讨论】:

    • 谢谢,但我需要在索引时间而不是查询时间。
    • 有什么理由特别在索引时间这样做吗? Elasticsearch 弃用了 5.0 elastic.co/guide/en/elasticsearch/reference/7.11/… 上的索引时间提升,并提供更多信息,也许我可以向您推荐另一种方法。
    • 抱歉回复晚了,但是是的,我知道 boosting 已被弃用,我正在寻找其他方法来帮助提高ondemand 以外的其他记录的分数或降低ondemand 的分数。
    • 我可以在查询时完成,但我使用elasticsearch_dsl.query Q 在python中查询elasticsearch实例。如果您知道有任何方法可以在那里做到这一点,那就太好了。
    • 现在我明白了。我可以重现 python dsl 格式的增强查询。我将编辑我的答案。如果有用请告诉我
    猜你喜欢
    • 2021-06-04
    • 1970-01-01
    • 2017-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-10
    相关资源
    最近更新 更多