弄了半天,终于在全部环境下搞店。
我自己的版本:(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屏蔽了。
4、1.5.3之后,以及1.4.8,都默认不再支持_groovy。怎么办?如果按照他文档建议的方式,通过一个文件来传递脚本,无疑太笨了。我研究了半天,发现可以在ES的配置文件里加这句:
script.groovy.sandbox.enabled: true
重启ES,搞定,可以用了。
5、你要说不安全嘛?当然,ES建议你可以使用express language,那个实在有点弱,好像不支持indexOf。我实在是一个很懒和不愿意把代码变长的程序员。
如果你有更好的方法,欢迎告诉我。