Elastic Search使用ids来排序

弄了半天,终于在全部环境下搞店。

网上有一个版本,但不能使用,有点过于复杂:

http://damienalexandre.fr/post/elasticsearch-ids-query-order

我自己的版本:(PHP)

$this->es_sort = [
    '_script'=>[
        "script"    =>  "ids.indexOf(doc['_uid'].value.replace('{$this->type}#',''));",
        "type"      =>  "number",
        "params"    => [
            "ids"   =>  $ids
        ],
        "order"     =>  $order
    ]
];

如果是纯Query的版本,我也放一个出来给大家方便测试吧:(请自行修改ID及type的值)

{
    "query": {
    "ids": {
        "values": [
            "55088c72662a07fd758b457a",
            "551fd6d6662a078ffe8b4578"
        ]
    }
  },
  "sort": {
    "_script": {
        "script": "return ids.indexOf(doc['_uid'].value.replace('product#',''));",
      "type": "number",
      "params": {
            "ids": [
                "55088c72662a07fd758b457a",
                "551fd6d6662a078ffe8b4578"
            ],
        "order": "sac"
      }
    }
  }
}

我测试的elastic版本分别有:1.1、1.4.1、1.5.3,都不一样。我大概总结一下。

1、网站这个获得当前文档的_id值的方法现在新的ES都不能用了。

id    = org.elasticsearch.index.mapper.Uid.idFromUid(doc['_uid'].value);

2、我用一个迂回的方法拿到这个_id,留意这句:

ids.indexOf(doc['_uid'].value.replace('{$this->type}#',''));

3、还有最要命的一个问题,一开头我怎么测试都不行,弄了大半天。后来很仔细看那一长段的exception信息,我怀疑是新版的ES安全性考虑,把默认的script语言groovy屏蔽了。见这页:

https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-scripting.html#_groovy_sandboxing

4、1.5.3之后,以及1.4.8,都默认不再支持_groovy。怎么办?如果按照他文档建议的方式,通过一个文件来传递脚本,无疑太笨了。我研究了半天,发现可以在ES的配置文件里加这句:

script.groovy.sandbox.enabled: true

重启ES,搞定,可以用了。

5、你要说不安全嘛?当然,ES建议你可以使用express language,那个实在有点弱,好像不支持indexOf。我实在是一个很懒和不愿意把代码变长的程序员。

如果你有更好的方法,欢迎告诉我。

Leave a Reply

Your email address will not be published. Required fields are marked *