2015-06-11 61 views
3

我的文档中有一个字段,它存储了一个整数数组。Elasticsearch函数根据数组中最大分数/嵌套的得分

的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

和评分功能主要是:“越接近foo.barinput,分数越高如果foo.barinput低得分只有一半好”

查询:

"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的原因。但是,它似乎只能遵守function_score中的functions数组,而不是(正如我所预期的)函数中可能的分数。


我读到关于使用doc['foo.bar'].values(价值小号而不是值)的地方,但我不知道如何在这种情况下使用它。

你有一个想法,如何得到这个工作?

回答

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" 
     } 
    } 
} 
+0

不将上述溶液的工作? – keety