在Elasticsearch-PHP中,[terms]查询不支持出现错误
事件
针对 Elasticsearch(版本6.8.5)使用 Elasticsearch-PHP 创建了包含 terms 语句的查询,并执行了搜索(_search),结果出现以下错误:
[terms] 查询不支持查找元素内的[0]。
应该有的形象
如果将以下数组传递给Elasticsearch的terms查询,则$accounts = [“aaa”, “ccc”]。
使用 Elasticsearch 进行如下处理。
"terms": {
"account": ["aaa", "ccc"]
}
这次出错的情况
首先,用PHP删除数组的中间元素,并使索引不连续。
$accounts = ["aaa", "bbb", "ccc"];
unset($accounts[1]); ◆"bbb" を削る
print_r($accounts);
* 配列の添え字はこんな感じになる
Array
(
[0] => aaa
[2] => ccc
)
用 PHP 将此数组传递给 Elasticsearch。
$client = Elasticsearch\ClientBuilder::create()
->setHosts(["localhost:9200"])->build();
$client->search([
"index" => "test_index",
"body" => [
"query" => [
"terms" => ["account" => $accounts]
]
]
]);
然后,Elasticsearch 将其作为以下查询进行处理。
"terms": {
"account": {
"0": "aaa",
"2": "bbb"
}
}
在查询项里的查找元素中不支持关键字“0”,导致出现错误。
总结原因
如果使用Elasticsearch-PHP,当数组(例如terms句的搜索值)在body内的索引不是从0开始,或者中间的数字被跳过,Elasticsearch会将其识别为对象,并产生意外的错误。
答案有很多。
(1) 推荐的方法
如果在 Elasticsearch-PHP 的 body 中想要指定一个数组,可以使用如 array_values 等方法,将数组的索引调整为从0开始、没有缺失的连续数列。我个人认为在使用数组的地方做 array_values 操作更加方便。
(2) 也可以直接將 JSON 字符串傳遞給 body,這樣就可以直接以 JSON 字符串方式定義並傳遞數組。
然而,在PHP中使用这种方法非常繁琐。
与Python不同,由于{}不是数组,因此需要直接编写查询语句。
变量展开也经常出现许多点(.),使得代码难以阅读。
此外,还需要注意,使用 json_encode 后,不完整的数组会被转换成对象。