弹性搜索。基于文档字段的动态评分

时间:2018-10-09 07:45:10

标签: elasticsearch

嗨,我正在使用Elasticsearch 6.4,并且试图为我的问题找到任何可行的解决方案。所以我的问题是我有文档,并且我尝试根据查询的ID进行评分。简化的文档结构如下所示:

{
    "rates": [
     { "id": 1, "score_rate": 4.0},
     { "id": 2, "score_rate": 5.0}, 
     { "id": 3, "score_rate": 0.0}
   ]
}

费率字段是嵌套的。

  1. 我第一次尝试根据查询script_score函数实现此目标:

    {"script_score":{"script":{"params":{"id":1,"min":0.0},"id":"secondary_rate"}}}
    

secondary_rate是轻松编写脚本的地方

double min_threshold = (double) params.min;
double score = min_threshold;

for (int i = 0; i < params._source.rates.length; ++i){
     def rate = params._source.rates[i];
     if (rate.id == params.id){
        c_score = category.score_rate;
        break;
}
}
return c_score;

但这无法正常工作,因为无法在整个doc['rates']的脚本中访问嵌套字段,并且_source字段在script_functions中不再可用(https://discuss.elastic.co/t/painless-null-pointer-exception/128245)。

  1. 第二次尝试使用NestedQuery和FieldValueFactor的组合 类似于https://discuss.elastic.co/t/nested-value-on-function-score/29935/2的内容。但是不幸的是,NestedQuery进行了第二次查询,然后使用根查询进行联接(我无法控制如何执行联接)结果,并且如果根查询为空,则NestedQuery的结果仅添加到根结果中。我的业务逻辑无法接受这种行为。

  2. 在第三次尝试时,我尝试将Rates字段重新索引为数组并在其中编码有关id的信息。因此,上面示例中的字段将如下所示: { "rates": [0, 4.0, 5.0, 0.0]}

    同样,我使用脚本函数,但是不能保证元素的顺序(来自官方的Elastic Search docs数组,被视为“值的袋子”)。在元素中 与索引时间的顺序相同,我需要使用_source字段(在6.4中不可用)。

因此,我对这个问题有些执着,不知道如何解决。因此,任何建议或提示都非常欢迎。预先谢谢你

1 个答案:

答案 0 :(得分:0)

如果您知道如何使其正常工作,请在评论中写下。 但我知道我创建了解决方法:

因为费率数组的大小相对较小。我设法为每个值动态创建Float字段,然后在搜索时将这些字段的名称作为参数传递给我的script_score(参数rates_keys),然后对这些值求和。因此,无痛功能看起来就像:

double add_score = 0.0;
String key;
for (int i = 0; i != params.rates_keys.length; ++i){
    rate_key = params.rates_keys[i];
    if(!doc[rate_key].empty) add_score += doc[rate_key].value;
}
return add_score;