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

ElasticSearch:使用文档PT.2中的自定义分数字段影响评分

裴弘
2023-03-14

有这些文件的:

{
  "created_at" : "2017-07-31T20:30:14-04:00",
  "description" : null,
  "height" : 3213,
  "id" : "1",
  "tags" : [
    {
      "confidence" : 65.48948436785749,
      "tag" : "beach"
    },
    {
      "confidence" : 57.31950504425406,
      "tag" : "sea"
    },
    {
      "confidence" : 43.58207236617374,
      "tag" : "coast"
    },
    {
      "confidence" : 35.6857910950816,
      "tag" : "sand"
    },
    {
      "confidence" : 33.660057321079655,
      "tag" : "landscape"
    },
    {
      "confidence" : 32.53252312423727,
      "tag" : "sky"
    }
  ],
  "width" : 5712,
  "color" : "#0C0A07",
  "boost_multiplier" : 1
}

{
  "created_at" : "2017-07-31T20:43:17-04:00",
  "description" : null,
  "height" : 4934,
  "id" : "2",
  "tags" : [
    {
      "confidence" : 84.09123410403951,
      "tag" : "mountain"
    },
    {
      "confidence" : 56.412795342449456,
      "tag" : "valley"
    },
    {
      "confidence" : 48.36547551196872,
      "tag" : "landscape"
    },
    {
      "confidence" : 40.51100450186575,
      "tag" : "mountains"
    },
    {
      "confidence" : 33.14263528292239,
      "tag" : "sky"
    },
    {
      "confidence" : 31.064394646169404,
      "tag" : "peak"
    },
    {
      "confidence" : 29.372,
      "tag" : "natural elevation"
    }
  ],
  "width" : 4016,
  "color" : "#FEEBF9",
  "boost_multiplier" : 1
}

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

我在SO,ElasticSearch:文档中自定义分数字段影响评分中发现了这个问题

但是当我尝试接受的解决方案(我在ES服务器中启用了脚本)时,它返回的两个文档都有_score1.0,而不管搜索词是什么。以下是我尝试的查询:

{
  "query": {
    "nested": {
      "path": "tags",
      "score_mode": "sum",
      "query": {
        "function_score": {
          "query": {
            "match": {
              "tags.tag": "coast landscape"
            }
          },
          "script_score": {
            "script": "doc[\"confidence\"].value"
          }
        }
      }
    }
  }
}

我还尝试了@Yahermann在注释中建议的方法,将“script_score”替换为“field_value_factor”:{“field”:“friency”},结果仍然相同。你知道为什么失败了吗,或者有更好的方法吗?

为了获得完整的图像,下面是我使用的映射定义:

{
  "mappings": {
    "photo": {
      "properties": {
        "created_at": {
          "type": "date"
        },
        "description": {
          "type": "text"
        },
        "height": {
          "type": "short"
        },
        "id": {
          "type": "keyword"
        },
        "tags": {
          "type": "nested",
          "properties": {
            "tag": { "type": "string" },
            "confidence": { "type": "float"}
          }
        },
        "width": {
          "type": "short"
        },
        "color": {
          "type": "string"
        },
        "boost_multiplier": {
          "type": "float"
        }
      }
    }
  },
  "settings": {
    "number_of_shards": 1
  }
}

更新下面@Joanna的回答,我尝试了查询,但事实上,无论我在match query、coast、foo和bar中放什么,它总是返回两个文档,并且它们的score都为1.0,我在Docker中的elasticsearch 2.4.6、5.3、5.5.1上尝试了它。以下是我得到的回应:

HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Content-Length: 1635

{"took":24,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":2,"max_score":1.0,"hits":[{"_index":"my_index","_type":"my_type","_id":"2","_score":1.0,"_source":{
  "created_at" : "2017-07-31T20:43:17-04:00",
  "description" : null,
  "height" : 4934,
  "id" : "2",
  "tags" : [
    {
      "confidence" : 84.09123410403951,
      "tag" : "mountain"
    },
    {
      "confidence" : 56.412795342449456,
      "tag" : "valley"
    },
    {
      "confidence" : 48.36547551196872,
      "tag" : "landscape"
    },
    {
      "confidence" : 40.51100450186575,
      "tag" : "mountains"
    },
    {
      "confidence" : 33.14263528292239,
      "tag" : "sky"
    },
    {
      "confidence" : 31.064394646169404,
      "tag" : "peak"
    },
    {
      "confidence" : 29.372,
      "tag" : "natural elevation"
    }
  ],
  "width" : 4016,
  "color" : "#FEEBF9",
  "boost_multiplier" : 1
}
},{"_index":"my_index","_type":"my_type","_id":"1","_score":1.0,"_source":{
  "created_at" : "2017-07-31T20:30:14-04:00",
  "description" : null,
  "height" : 3213,
  "id" : "1",
  "tags" : [
    {
      "confidence" : 65.48948436785749,
      "tag" : "beach"
    },
    {
      "confidence" : 57.31950504425406,
      "tag" : "sea"
    },
    {
      "confidence" : 43.58207236617374,
      "tag" : "coast"
    },
    {
      "confidence" : 35.6857910950816,
      "tag" : "sand"
    },
    {
      "confidence" : 33.660057321079655,
      "tag" : "landscape"
    },
    {
      "confidence" : 32.53252312423727,
      "tag" : "sky"
    }
  ],
  "width" : 5712,
  "color" : "#0C0A07",
  "boost_multiplier" : 1
}
}]}}

更新-2我在so:elasticsearch:“function_score”上找到了这个:“boost_mode”:“replace”忽略函数得分

它基本上是说,如果函数不匹配,它返回1。这是有道理的,但我正在为相同的文档运行查询。真让人困惑。

最后更新我终于发现了问题,真蠢。ES101,如果你发送GET请求到搜索api,它返回所有得分为1.0的文档:)你应该发送POST请求...Thx很多@Joanna,它工作得很完美!!!

共有1个答案

姚星宇
2023-03-14

您可以尝试这个查询-它将评分与:freusteboost_multiplier字段结合起来:

{
  "query": {
    "function_score": {
        "query": {
            "bool": {
                "should": [{
                    "nested": {
                      "path": "tags",
                      "score_mode": "sum",
                      "query": {
                        "function_score": {
                          "query": {
                            "match": {
                              "tags.tag": "landscape"
                            }
                          },
                          "field_value_factor": {
                            "field": "tags.confidence",
                            "factor": 1,
                            "missing": 0
                          }
                        }
                      }
                    }
                }]
            }
        },
        "field_value_factor": {
            "field": "boost_multiplier",
            "factor": 1,
            "missing": 0
        }
      }
    }
} 

当我使用coast术语搜索时,它返回:

    ID=1
  • 文档,因为只有这个文档有这个术语,得分为“_score”:100.27469.

当我使用横向术语进行搜索时,它返回两个文档:

    ID=2且得分为_score:85.83046的
  • 文档 ID=1且得分“_score”:59.7339
  • 文档

id=2的文档具有较高的置信度字段值时,其得分较高。

当我使用海岸景观术语进行搜索时,它返回两个文档:

    ID=1且得分“_score”:160.00859的
  • 文档 ID=2且得分为_score:85.83046
  • 文档

尽管ID=2的文档具有更高的frience字段值,但ID=1的文档具有两个匹配的单词,因此得分要高得多。通过更改“factor”:1参数的值,可以决定置信度对结果的影响程度。

当我索引一个新文档时,会发生更有趣的事情:假设它与ID=2的文档几乎相同,但是我设置了“boost_multiplier”:4“id”:3:

{
  "created_at" : "2017-07-31T20:43:17-04:00",
  "description" : null,
  "height" : 4934,
  "id" : "3",
  "tags" : [
    ...
    {
      "confidence" : 48.36547551196872,
      "tag" : "landscape"
    },
    ...
  ],
  "width" : 4016,
  "color" : "#FEEBF9",
  "boost_multiplier" : 4
}

使用海岸景观术语运行相同的查询将返回三个文档:

    ID=3且得分为_score:360.02664的
  • 文档 ID=1且得分“_score”:182.09859
  • 文档 ID=2且得分“_score”:90.00666
  • 文档

尽管ID=3的文档只有一个匹配的单词(lands),但其boost_multipultier值大大提高了得分。这里,使用“factor”:1,还可以决定这个值应该增加多少得分,使用“missing”:0决定如果没有索引这样的字段应该发生什么。

 类似资料:
  • 问题内容: 拥有这些文件: 和 我想获得基于每个标签的置信度值计算的_score。例如,如果您搜索“ mountain”,则显然应该仅返回ID为1的文档;如果您搜索“ landscape”,则得分2应该高于1,因为景观对2的置信度高于1(48.36 vs 33.66)。如果您搜索“ coast landscape”,则此时间得分1应该高于2,因为doc 1在标签数组中同时包含了Coast和Land

  • 问题内容: 我有一组通过NLP算法从文本中提取的单词,以及每个文档中每个单词的相关分数。 例如 : 我希望每个文档中的match 都可以影响ES给它的给定值,或者乘以或加到上,以影响结果文档的最终(依次,顺序)。有什么办法可以做到这一点? 问题答案: 解决此问题的另一种方法是使用嵌套文档: 首先设置映射以创建一个嵌套文档,这意味着每个/ 文档将在内部作为单独的文档建立索引: 然后索引您的文档: 并

  • 我正在向elasticsearch发送查询,它会响应其文档中字段的未知顺序。我如何修复elsasticsearch返回文档中字段的顺序?我的意思是,我正在发送这个查询: 当它回应时,它给了我一些不正常的东西。我最后想将其转换为csv,并修复csv标题。有什么方法可以让我得到像doc1:{“field1”,“field2”,“field3”,“field14”}doc2:{“field1”,“fie

  • 有没有办法使用“ACF分类法字段”来影响“自定义分类法”的帖子计数?现在我正在使用ACF分类法字段,但我的自定义分类法分配了0篇文章。 这可能吗?我尝试这样做是因为它对最终用户更友好,ACF更灵活;如果我需要用户只选择一个分类法并进行其他限制,我可以对其进行限制。

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

  • 我在修改我安装的WordPress流行帖子插件时遇到了一些问题。 它可以选择从自定义字段获取缩略图,我已将其输入为“image_facebook”。但是缩略图没有显示。 在检查代码时,我发现imgsrc有post id而不是返回图像URL。 我已经把问题缩小到我安装的另一个插件http://wordpress.org/plugins/advanced-custom-fields/ 当它处于活动状态