仅调整某些查询的相关性分数

Tweaking relevance score of only certain queries

我有一个用例,当用户根据搜索词搜索某些搜索词时,我需要根据该搜索词的总结果对某些文档进行排名。

到目前为止我尝试过的:

我已将嵌套字段 tuning 添加到索引中的文档中,该字段将具有这些自定义提升。

{
    _id: 1234,
    'name': 'Fancy potato masher',
    'tuning': [
        {'term': 'potato', 'rank': 5},
        {'term': 'masher', 'rank': 10}, 
    ]
},
{
    _id: 2345,
    'name': 'Decent potato masher',
    'tuning': [
        {'term': 'potato', 'rank': 3},
        {'term': 'masher', 'rank': 7},
    ]
},
{
    _id: 3456,
    'name': 'Useless potato masher',
    'tuning': [
        {'term': 'potato', 'rank': -5},
        {'term': 'masher', 'rank': -7},
    ]
},
{
    _id: 4567,
    'name': 'Ordinary potato masher',
    'tuning': []
}

所以这里当我们搜索potatomasher时,我希望结果的顺序是1234, 2345, 4567, 3456

我的 sort 查询部分如下所示:

{
    'sort': {
        'tuning.rank' => {
            'order' => 'desc',
            'nested' => {
                'path' => 'tuning',
                'filter' => {
                    'match' => {
                        'tuning.term' => 'potato'
                    }
                }

            }
        },
    }
}

我的结果是1234, 2345, 3456, 4567的顺序。所以基本上任何缺少 tuning 数据的东西都会出现在最后,而不是排名为负的数据。

如何在不花哨学习排名等的情况下正常解决这个问题

只需添加 missing 参数,如下例所示。

另请注意,如 link post [ 中所述,您使用 nested_filternested_path 的方式已被弃用=70=]ES 6.2版本。

我已经提到了如何使用最新的和已弃用的 DSL 来获得您想要的东西。根据您使用的版本随意使用。

查询 ES 6.2 之前的版本

POST <your_index_name>/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match_all": {}      //query logic as per your requirement
        }
      ]
    }
  },
  "sort": [
    {
      "tuning.rank": {
        "order": "desc",
        "nested_path": "tuning",
        "nested_filter": {
            "match": {
              "tuning.term": "potato"
            }
        },
        "missing": "0"                    <------ Note this.
      }
    }
  ]
}

在上面的查询中,只关注排序逻辑,我刚刚添加了值为 0missing 参数,这意味着如果字段 tuning.term 丢失, 令排序值为 0 以便对文档进行相应排序。

查询 ES 6.2+ 版本

POST <your_index_name>/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match_all": {}
        }
      ]
    }
  },
  "sort":[
    {
      "tuning.rank":{
        "order": "desc",
        "nested":{
          "path": "tuning",
          "filter":{
            "match":{
              "tuning.term": "potato"
            }
          }
        },
        "missing": "0"
      }
    }
  ]
}

以下是响应在我的机器中的显示方式:

回复:

{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 4,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [
      {
        "_index" : "someindex",
        "_type" : "_doc",
        "_id" : "1234",
        "_score" : null,
        "_source" : {
          "name" : "Fancy potato masher",
          "tuning" : [
            {
              "term" : "potato",
              "rank" : 5
            },
            {
              "term" : "masher",
              "rank" : 10
            }
          ]
        },
        "sort" : [
          5
        ]
      },
      {
        "_index" : "someindex",
        "_type" : "_doc",
        "_id" : "2345",
        "_score" : null,
        "_source" : {
          "name" : "Decent potato masher",
          "tuning" : [
            {
              "term" : "potato",
              "rank" : 3
            },
            {
              "term" : "masher",
              "rank" : 7
            }
          ]
        },
        "sort" : [
          3
        ]
      },
      {
        "_index" : "someindex",
        "_type" : "_doc",
        "_id" : "4567",
        "_score" : null,
        "_source" : {
          "name" : "Ordinary potato masher",
          "tuning" : [ ]
        },
        "sort" : [
          0
        ]
      },
      {
        "_index" : "someindex",
        "_type" : "_doc",
        "_id" : "3456",
        "_score" : null,
        "_source" : {
          "name" : "Fancy potato masher",
          "tuning" : [
            {
              "term" : "potato",
              "rank" : -5
            },
            {
              "term" : "masher",
              "rank" : -7
            }
          ]
        },
        "sort" : [
          -5
        ]
      }
    ]
  }
}

现在,如果您 运行 查询,您的结果将相应地排序。

相关性的更新答案:

你在上面看到我正在使用自定义排序,就此而言,相关性不会显示出来。

默认情况下,如果您不使用任何排序逻辑,结果将按相关性排序,您将能够查看 _score 值。

另请注意,我使用的是 match_all,它会给每个文档打 1 分。因此,如果您删除排序逻辑,您将在我共享的查询中返回所有得分为 1 的文档。

相关性是一个复杂的话题,它在很大程度上取决于您的用例。我建议您花些时间研究 function_score 查询,以便您了解如何 影响 分数。稍微尝试一下,您就会慢慢开始理解它是如何工作的。

至于您的评论,如果您还想显示或显示 _score,您只需在排序逻辑中也添加 _score 字段即可。所以首先,它会按 tuning.rank 对文档进行排序,然后它会根据 _score.

进行排序

下面是它是如何完成的。

POST <your_index_name>/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match_all": {}
        }
      ]
    }
  },
  "sort":[
    {
      "tuning.rank":{
        "order": "desc",
        "nested":{
          "path": "tuning",
          "filter":{
            "match":{
              "tuning.term": "potato"
            }
          }
        },
        "missing": "0"
      }
    },
    {
      "_score": { "order": "desc" }
    }
  ]
}

回复:

{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 4,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [
      {
        "_index" : "someindex",
        "_type" : "_doc",
        "_id" : "1234",
        "_score" : 1.0,
        "_source" : {
          "name" : "Fancy potato masher",
          "tuning" : [
            {
              "term" : "potato",
              "rank" : 5
            },
            {
              "term" : "masher",
              "rank" : 10
            }
          ]
        },
        "sort" : [
          5,
          1.0
        ]
      },
      {
        "_index" : "someindex",
        "_type" : "_doc",
        "_id" : "2345",
        "_score" : 1.0,
        "_source" : {
          "name" : "Decent potato masher",
          "tuning" : [
            {
              "term" : "potato",
              "rank" : 3
            },
            {
              "term" : "masher",
              "rank" : 7
            }
          ]
        },
        "sort" : [
          3,
          1.0
        ]
      },
      {
        "_index" : "someindex",
        "_type" : "_doc",
        "_id" : "4567",
        "_score" : 1.0,
        "_source" : {
          "name" : "Ordinary potato masher",
          "tuning" : [ ]
        },
        "sort" : [
          0,
          1.0
        ]
      },
      {
        "_index" : "someindex",
        "_type" : "_doc",
        "_id" : "3456",
        "_score" : 1.0,
        "_source" : {
          "name" : "Fancy potato masher",
          "tuning" : [
            {
              "term" : "potato",
              "rank" : -5
            },
            {
              "term" : "masher",
              "rank" : -7
            }
          ]
        },
        "sort" : [
          -5,
          1.0
        ]
      }
    ]
  }
}

另外,为了让您了解相关文档不是按相关性而是根据您的排序逻辑排序的,请尝试 运行 执行以下查询:

POST <your_index_name>/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "potato decent"
          }
        }
      ]
    }
  },
  "sort":[
    {
      "tuning.rank":{
        "order": "desc",
        "nested":{
          "path": "tuning",
          "filter":{
            "match":{
              "tuning.term": "potato"
            }
          }
        },
        "missing": "0"
      }
    },
    {
      "_score": { "order": "desc" }
    }
  ]
}

您可以在结果中看到,_score 值较高的文档仍然会出现在较低的位置,因为我们主要基于 tuning.rank.

进行排序

希望对您有所帮助!