处理倒数函数时如何防止Elasticsearch中的分片故障

时间:2019-04-02 05:44:42

标签: elasticsearch elastic-stack

我必须执行弹性搜索查询,在这里我需要修改查询检索的文档分数。我正在使用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"
 }

2 个答案:

答案 0 :(得分: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)"
            }
        }

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

答案 1 :(得分:0)

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

{
    "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"
    }
}

在这里,首先它将根据布尔查询过滤数据,然后仅ES会根据过滤后的数据执行得分计算。因此,将导致导致分片失败的等级值(即0和NULL)被过滤掉。