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

Elasticsearch数组评分

凌俊语
2023-03-14

我使用elasticsearch在我的类型中搜索多个数组字段,看起来像

t1 =  { field1: ["foo", "bar"],
        field2: ["foo", "foo", "foo", "foo"]
        field3: ["foo", "foo", "foo", "foo", "foo", "foo"]
}

然后我使用multi\u match查询来获取匹配项

multi_match: { query: "foo",
                fields: "fields*"
              }

当计算t1的分数时,elasticsearch将字段1、字段2和字段3中的查询分数相加,这正是我想要的。然而,他们的贡献并不相等,字段3对得分的贡献最大,因为“foo”在那里多次出现。

我现在想通过不将所有数组条目的分数相加,而是取最大值来计算每个数组字段中的分数。在我的示例中,所有包含的字段都将具有相同的分数,因为它们都有一个完全匹配。

elasticsearch论坛上已经提出了这个问题,但到目前为止尚未得到回答。

共有1个答案

应俊爽
2023-03-14

我自己也被这个难倒了,看起来真的应该有一个简单的、内置的方法来指定max而不是sum。

不确定这是否正是您想要的,因为您会丢失数组中任何特定项目的匹配分数。因此,您不会获得最佳特定项目的匹配分数的最大值,只有一个布尔值(如果有匹配的话)。如果是更细微的东西(比如一个人的全名,您希望第一个和最后一个更好地匹配,而不是只有一个或另一个),这可能是不可接受的,因为您正在丢弃您的分数。

如果这是可以接受的,这个解决方案似乎是可行的:

{function_score: {
  query: {bool: {should: [
    {term: {field1: 'foo'}},
    {term: {field2: 'foo'}},
    {term: {field3: 'foo'}},
  ]}},  
  functions: [
    {filter: {term: {field1: 'foo'}}, weight: 1},
    {filter: {term: {field2: 'foo'}}, weight: 1},
    {filter: {term: {field2: 'foo'}}, weight: 1},
  ],
  score_mode: 'sum',
  boost_mode: 'replace',
}}

我们需要“查询”部分为我们提供进一步过滤的结果,即使我们丢弃分数。这似乎真的应该是一个过滤器,但只是将同样的东西包装在过滤的查询中是行不通的。这里可能有更好的选择。

然后,如果该字段上有匹配项,则权重函数基本上给出1,否则给出0。score\u模式告诉它对这些权重求和,所以在您的情况下,它们都匹配,所以我们得到3。boost\u模式告诉我们如何与原始查询相结合,“replace”告诉它忽略原始查询分数(这有一个问题,您提到了一个数组中的多个匹配项被求和)。所以,这个查询的总分是3,因为有3个匹配项。

这对我来说似乎更复杂,但在我相对有限的测试中,我没有注意到性能问题或任何东西。如果更熟悉elasticsearch的人有更好的答案,我希望看到更好的答案。

 类似资料:
  • 问题内容: 我要寻找的是关于ElasticSearch(Lucene)的默认评分机制实际工作方式的简单明了的解释。我的意思是,它使用Lucene评分,还是使用自己的评分? 例如,我想通过“名称”字段搜索文档。我使用.NET NEST客户端编写查询。让我们考虑这种查询: 转换为此类JSON查询: 搜索大约有110万个文档。我得到的回报是(这只是结果的一部分,由我自己格式化): 其中第一个字段只是一个

  • 问题内容: 我的Elasticsearch DB中有一个像这样的文档: 我希望能够使用此条件过滤我的文档:Documents标签数组必须具有标签1,标签3和标签2,但不能具有标签A。 我尝试使用布尔过滤器,但无法使其正常工作! 问题答案: 这是一种似乎可以完成您想要的方法:http : //sense.qbox.io/gist/4dd806936f12a9668d61ce63f39cb2c2845

  • 我无法在任何地方找到如何在ES自定义评分函数中测试空值的示例。根据文档,脚本是时髦的,根据日志,脚本是无痛的评估,但即使这样,我仍然对一些错误感到困惑 这似乎表明我正在尝试将双精度值cas到布尔值并提出,但我需要测试非空值。 我的评分脚本应该怎么写? 编辑:我知道在无痛中我不能使用三进制的<代码>?:运算符,所以我必须显式地编写< code>doc['xx']。值!= null。然而,对于用空值索

  • 显示评论组件: {:Comments("posts",$object_id)} <!-- 评论文章表里的某个id为$object_id的文章--> Comments方法说明: 参数1:评论内容所在的表,不带表前缀的表名称,如cmf_posts应该改为“posts”; 参数2:评论内容的id: 参数3:数组,目前支持tpl参数,如array("tpl"=>"comment_custom"),这样设

  • Mudu.Room.Comment 评论组件 获取评论页数 // 返回评论页数,类型为int var commentPage = Mudu.Room.Comment.GetPage() 发送评论 Mudu.Room.Comment.Send( // 要发送的评论文本,类型为string '活动很赞很给力', // 发送完成的回调函数,参数为response对象 function

  • 问题内容: 我正在ElasticSearch中实现自动完成索引,并且遇到了排序/评分问题。假设索引中包含以下字符串: 当我搜索“甜甜圈”时,我希望结果按术语位置来排序,如下所示: 我不知道如何做到这一点。字词排名未纳入默认的评分逻辑,而且我找不到找到方法。似乎很简单,尽管以前其他人也必须遇到这个问题。有人知道吗? 谢谢! 问题答案: 根据安德烈(Andrei)的答案,这是我最终得到的解决方案,并扩