Elasticsearch函数评分基于数组/嵌套中的最大分数

时间:2015-06-11 12:28:50

标签: elasticsearch scoring

我的文档中有一个字段,它存储一个整数数组。

Java类:

public class Clazz {
    public List<Foo> foo;

    public static Foo {
         public Integer bar;
         public Integer baz;
    }
}

映射:

"properties" : {
    "foo" : {
        "properties" : {
          "bar" : {
            "type" : "integer"
          },
          "baz" : {
            "type" : "integer"
          }
        }
    }
}

示例文档:

{
    id: 1
    foo: [
        { bar: 10 }, 
        { bar: 20 }
    ]
},

{
    id: 2
    foo: [
        { bar: 15 }
    ]
}

现在我想做我的得分。评分函数的值为input10

评分函数基本上是:&#34; foo.bar越靠近input,得分越高。如果foo.bar低于input,那么得分只有一半好&#34;

查询:

"function_score" : {
    "functions" : [ {
        "script_score" : {
            "script" : "if(doc['foo.bar'].value >= input) { (input - doc['foo.bar'].value) * 1 } else { (doc['foo.bar'].value - input) * 2 }",
            "lang" : "groovy",
            "params" : {
                "input" : 10
            }
      }
} ],
"score_mode" : "max",
"boost_mode" : "replace"

}

预期结果:

id 1应该是第一位的,因为foo.bar匹配input=10

会发生什么:

如果文档只有单个 foo.bar值,则评分可以正常运行。如果它是一个数组(就像在带有id 1的文档中那样),Elasticsearch似乎占据了数组中的最后一个值。

查询应该执行的操作:

获得最高分。这就是我使用score_mode: max的原因。但似乎这只是尊重functions中的function_score数组,而不是(正如我预期的那样)函数中可能的分数。

我在某处读过使用doc['foo.bar'].values(值 s 而不是值),但在这种情况下我不知道如何使用它。

你有什么想法,如何让这个工作?

1 个答案:

答案 0 :(得分:3)

使用groovy实现此目的的一种方法如下,即您可以使用值的最大列表方法。

示例:

{
   "query": {
      "function_score": {
         "functions": [
            {
               "script_score": {
                  "script": "max_score=doc[\"foo.bar\"].values.max();if(max_score >= input) {return (max_score - input);} else { return (max_score - input) *2;}",
                  "lang": "groovy",
                  "params": {
                     "input": 10
                  }
               }
            }
         ],
         "score_mode": "max",
         "boost_mode": "replace"
      }
   }
}