1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Elasticsearch-PHP で [terms] query does not support エラーが出る

Posted at

事象

Elasticsearch (Version 6.8.5) に対して、
Elasticsearch-PHP で terms 句を含む query を作って検索(_search)を行ったところ、以下のエラーが出た。
[terms] query does not support [0] within lookup element

あるべき姿

以下のような配列を 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 の query としては以下の様に扱われてしまう。

"terms": {
  "account": {
    "0": "aaa",
    "2": "bbb"
  }
}

"0" などという key は terms 句の中に存在しないためエラーになっていた。
[terms] query does not support [0] within lookup element

原因まとめ

Elasticsearch-PHP を利用する場合、
body 内の配列(例:terms 句の検索値)の添え字が0から始まらない、
または途中の数字が抜けている場合、
Elasticsearch 側で Object として認識されてしまい、予期せぬエラーを産む。

解決方法

(1) おすすめの方法
Elasticsearch-PHP の body 内で配列を指定したい場合、
array_values などで配列の添え字を 0から始まる歯抜けのない数列 に揃えること。
個人的には配列利用箇所で array_values するのが楽。

(2) body には JSON 文字列を渡すこともできるので、
直接 JSON 文字列として配列を定義して渡す。

ただ、この方法を PHP で使うのはかなりめんどくさい。
Pytohn と違って {} が配列ではないためベタで query を書く必要がある。
変数展開もピリオド(.)がたくさん出てきて見づらくなる。。。

あと、json_encode でも歯抜けの配列が Object に変わってしまうので注意が必要。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?