2015-06-11 63 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