当前位置: 首页 > 知识库问答 >
问题:

如何使elasticsearch评分考虑字段长度

公羊渝
2023-03-14

我创建了一个非常简单的测试索引,由以下5个条目组成:

{    "tags": [        { "topics": "music festival dance techno germany"}    ]}
{    "tags": [        { "topics": "music festival dance techno"}    ]}
{    "tags": [        { "topics": "music festival dance"}    ]}
{    "tags": [        { "topics": "music festival"}    ]}
{    "tags": [        { "topics": "music"}    ]}

然后我执行以下查询:

{
  "query": { 
    "bool": { 
      "should": [
        { "match": { "tags.topics": "music festival"}}
      ]
    }
  }
}

期望在结果中获得以下顺序:

1)“音乐节”

2)《音乐节舞曲》

然而,我得到了以下结果:

{
    "took": 4,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": 5,
        "max_score": 0.5753642,
        "hits": [
            {
                "_index": "testindex",
                "_type": "entry",
                "_id": "1",
                "_score": 0.5753642,
                "_source": {
                    "tags": [
                        {
                            "topics": "music festival dance techno germany"
                        }
                    ]
                }
            },
            {
                "_index": "testindex",
                "_type": "entry",
                "_id": "3",
                "_score": 0.5753642,
                "_source": {
                    "tags": [
                        {
                            "topics": "music festival dance"
                        }
                    ]
                }
            },
            {
                "_index": "testindex",
                "_type": "entry",
                "_id": "4",
                "_score": 0.42221835,
                "_source": {
                    "tags": [
                        {
                            "topics": "music festival"
                        }
                    ]
                }
            },
            {
                "_index": "testindex",
                "_type": "entry",
                "_id": "2",
                "_score": 0.32088596,
                "_source": {
                    "tags": [
                        {
                            "topics": "music festival dance techno"
                        }
                    ]
                }
            },
            {
                "_index": "testindex",
                "_type": "entry",
                "_id": "5",
                "_score": 0.2876821,
                "_source": {
                    "tags": [
                        {
                            "topics": "music"
                        }
                    ]
                }
            }
        ]
    }
}

它的顺序似乎完全随机,除了最低分只匹配一个词。

是什么导致了这种情况,我可以改变什么(在映射、索引或搜索过程中)来获得预期的顺序?

注意:对于非完美匹配查询也是如此。搜索“音乐舞蹈”仍然应该产生3个单词条目作为第一个结果,所以使用或增加术语查询似乎是不可能的。

共有1个答案

谈桐
2023-03-14

正如我在这个答案中所描述的,评分/相关性在ElasticSearch中并不是最容易的主题。

我试图为你找到解决方案,目前我有这样的东西。

文件:

{ "tags": [ { "topics": ["music", "festival", "dance", "techno", "germany"]} ], "topics_count": 5 }
{ "tags": [ { "topics": ["music", "festival", "dance", "techno"]} ], "topics_count": 4 }
{ "tags": [ { "topics": ["music", "festival", "dance"] } ], "topics_count": 3 }
{ "tags": [ { "topics": ["music", "festival"]} ], "topics_count": 2 }
{ "tags": [ { "topics": ["music"]} ], "topics_count": 1 }

和查询:

{
  "query": {
    "bool": {
      "should": [
        {
          "function_score": {
            "query": {
              "terms_set": {
                "tags.topics" : {
                  "terms" : ["music", "festival"],
                  "minimum_should_match_script": {
                    "source": "params.num_terms"
                  }
                }
              }
            },
            "script_score" : {
              "script" : {
                "source": "_score * Math.sqrt(1.0 / doc['topics_count'].value)"
              }
            }
          }
        },
        {
          "function_score": {
            "query": {
              "terms_set": {
                "tags.topics" : {
                 "terms" : ["music", "festival"],
                 "minimum_should_match_script": {
                    "source": "doc['topics_count'].value"
                  }
                }
              }
            },
            "script_score" : {
              "script" : {
                "source": "_score * Math.sqrt(1.0 / doc['topics_count'].value)"
              }
            }
          }
        }
      ]
    }
  }
}

它并不完美。还需要一些改进。在这个示例中,它对[“music”,“festival”][“music”,“dance”]工作得很好(在ES 6.2上进行了测试),但我猜在其他结果中,它不会像您预期的那样100%工作。主要是因为相关性/评分的复杂性。但是你现在可以读到更多关于我使用过的东西,并试图改进它。

 类似资料:
  • 问题内容: 我知道,弹性查询在计算查询检索的文档分数时会考虑字段的长度。字段越短,权重越高(请参见字段长度范数)。 我喜欢这种行为:当我搜索我在更感兴趣比。 现在,我想尝试增强这些功能,比方说,我想使其重要性加倍。 我知道可以使用功能分数来修改分数,并且我想我可以通过脚本分数来实现我想要的。 我试图像这样向得分添加另一个字段长度范数: 但是我失败很严重,得到了这个错误: 编辑: 我的第一个错误是我

  • 问题内容: 我正在建立搜索,但需要使用不同的分析器分析1个字段。我的问题是,对于一个字段,我需要在其上安装一个分析器以进行词干分析(雪球),然后还需要一个分析器将完整的单词保留为一个标记(关键字)。我可以通过以下索引设置来使其工作: 在标题字段中搜索单个单词时出现问题。如果其中装有“帽子里的猫”,它将存储为“帽子里的猫”,但是如果我搜索猫,我什么也得不到。 这是否有可能实现?还是我需要有2个单独的

  • 我使用elasticsearch在我的类型中搜索多个数组字段,看起来像 然后我使用multi\u match查询来获取匹配项 当计算t1的分数时,elasticsearch将字段1、字段2和字段3中的查询分数相加,这正是我想要的。然而,他们的贡献并不相等,字段3对得分的贡献最大,因为“foo”在那里多次出现。 我现在想通过不将所有数组条目的分数相加,而是取最大值来计算每个数组字段中的分数。在我的示

  • 有这些文件的: 和 我想要获得_score根据每个标记的置信度值计算出来的值。例如,如果您搜索“mountain”,它应该只返回id为1的doc,显然,如果您搜索“landsacture”,得分2应该高于1,因为landsacture在2中的置信度高于1(48.36 vs 33.66)。如果您搜索“海岸景观”,这个时间得分1应该高于2,因为doc1在tags数组中同时包含海岸和景观。我还想用“bo

  • 问题内容: 我试图获取记录在“标题”中,然后是X个字符。 注意:并非所有记录都包含标题字段。 我努力了: 结果,我得到这个错误: 我该如何解决? 问题答案: 您需要考虑到某些文档可能具有空字段。因此,您可以使用常规的空安全运算符。另外,请确保改用POST方法:

  • 我试图通过根据场值提升_score来摆脱弹性搜索中的排序。这是我的场景: 我的文档中有一个字段:应用日期。这是自EPOC以来经过的时间。我希望具有更大应用日期(最近)的记录具有更高的分数。 如果两个文档的分数相同,我想在另一个字符串类型的字段上对它们进行排序。说“状态”是另一个可以有值的字段(可用、进行中、关闭)。所以,具有相同应用程序日期的文档应该根据状态_score。可用应该有更多的分数,进行