query stringが自由すぎてびっくりした話
Elasticsearchを使って実際に検索するときに便利なクエリがQueryStringQueryとSimpleQueryStringQueryです。これらはqueryでfieldを指定したりAND・OR・NOTを指定できたりするのでかなり自由度が高いクエリです。
この2つのクエリ、使う分にはかなり便利なのですが、分かってないで使うと非常に危なさそうだったので、備忘録代わりに書きます。
SimpleQueryStringQueryとQueryStringQueryはquery_stringのパラメータとして、fieldsを指定することで、そのfieldsの中から検索をすることができるのですが、QueryStringの場合、queryに直接fieldと値を指定されてしまうと、その条件で検索をかけてしまいます。
以下のmappingでindexを作成したとします。 sampleというtypeでidとuser_idというpropertyを定義しています。propertyはともにkeywordです。
{ "mappings": { "sample": { "properties": { "id": { "type": "keyword" }, "user_id": { "type": "keyword" } } } } }
上記のmappingのindexに以下のデータを入れているとします。
{ "id": "test1", "user_id": "user_id1"} { "id": "test2", "user_id": "user_id2"} { "id": "test3", "user_id": "user_id3"}
そして以下のクエリを投げると、まさかidがtest2のdocumentが引っこ抜けてしまいます。
GET sample/sample/_search { "query": { "query_string": { "query": "id:test2", "fields": ["user_id"] } } }
ちなみにSimpleQueryStringQueryの場合だと指定したfieldsから検索されるので検索結果は空で返ってきます。
まとめ
QueryStringQueryとSimpleQueryStringQueryはとても便利なのですが、私みたいによく分かっていない状態で使うと色々危ないので、無難に検索するのであれば、MultiMatchQueryを使うのが無難かもしれないです。もっと細かい検索(AND・OR・NOTなど)を使いたいのであれば、自前でquery builderを書いたほうがいいんですかね。