在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 后,不完整的数组会被转换成对象。

广告
将在 10 秒后关闭
bannerAds