【问题标题】:How to prevent shard failure in elasticsearch when dealing with reciprocal function处理倒数函数时如何防止elasticsearch中的分片失败
【发布时间】:2019-04-10 15:27:01
【问题描述】:

我必须执行弹性搜索查询,我需要修改查询检索到的文档的分数。我正在使用 function_score 在倒数函数的帮助下修改分数。以下是我的代码,

{
        "function_score": {
            "query": {
                "bool": {
                    "must": [{"match":{"course": "IT"}}]
                }
            },
            "functions": [{
                    "field_value_factor": {
                        "field": "users_score_nested.rank",
                        "modifier": "reciprocal",
                        "missing": 1
                    }
                }
            ],
            "boost_mode": "multiply",
            "score_mode": "sum"
        }
    }

在这里,我需要根据课程字段和排名字段的过滤器来更改我的分数。排名值可以有 0、NULL、1、2 之类的值。对于排名较高的候选人(最低排名值),分数应该很高。但由于 0 或 NULL 值分片失败发生。除了更改排名值之外,还有其他方法可以防止分片失败吗?或者我可以使用除倒数函数之外的任何其他函数吗?

我得到的错误如下,

{
    "root_cause": [{
        "type": "exception",
        "reason": "Result of field modification [reciprocal(0.0)] must be a number"
    }],
    "type": "search_phase_execution_exception",
    "reason": "all shards failed",
    "phase": "query"
 }

【问题讨论】:

    标签: elasticsearch elastic-stack


    【解决方案1】:

    您所能做的就是从数据中删除“users_score_nested.rank”,以便 function_score 查询的“missing”参数生效,倒数为 1。

    恐怕没有办法绕过异常。或者,您可以使用 function_score 查询的 script_score 参数

    "script_score" : {
                "script" : {
                    "source": "Math.pow(doc['users_score_nested']['rank']+1,-1)"
                }
            }
    

    注意:确保"rank" 字段的"type""integer",并且它作为映射的一部分包含在父级中。

    【讨论】:

    • Math.pow 函数会在排名值增加时增加分数,但在我的情况下它应该减少。假设排名 1 应该排在首位,而排名 10 应该更少。
    • 我猜 Math.pow(, -1) 与倒数相同。您可以通过在较小的数据集上触发上述查询并验证相应的分数来进行检查。
    • 我试过这个方法,但是当值为0或NULL时失败
    • 我假设排名是一个非负整数。如果数据中任何位置的 rank 为 -1,这将失败。
    • 在我的情况下,排名值可以包括 0 和 NULL
    【解决方案2】:

    最后,我找到了防止分片故障的方法。我做了以下工作,这帮助我避免了分片失败。

    {
        "function_score": {
            "query": {
                "bool": {
                    "must": [{"match":{"course": "IT"}},
                             {"terms":{"users_score_nested.rank": [1, 2]}}]
                }
            },
            "functions": [{
                    "field_value_factor": {
                        "field": "users_score_nested.rank",
                        "modifier": "reciprocal",
                        "missing": 1
                    }
                }
            ],
            "boost_mode": "multiply",
            "score_mode": "sum"
        }
    }
    

    这里,首先会根据 bool 查询过滤数据,然后对过滤后的数据只有 ES 进行分数计算。所以会过滤掉导致分片失败的rank值,即0和NULL。

    【讨论】:

      猜你喜欢
      • 2016-06-27
      • 2014-07-02
      • 2018-09-16
      • 2012-07-05
      • 1970-01-01
      • 1970-01-01
      • 2015-03-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多