アゴ乗せ日記

適当なポジティブ日記

スポンサーリンク

【Elasticsearch】query_stringとsimple_query_stringどっち使う?【感想】

Hey guys, what's up?

はろー

この記事を書くってことは....そうだす。不具合に出くわしたからなんだす。

先に結論

バリデーションチェックとかしたくないし、予期せぬエラーで止めたくないからsimple_query_string

元々は query_string を使用していた

クエリはこんな感じ

GET agodex/_search
{
  "from": 0,
  "size": "50",
  "query": {
    "bool": {
      "must": [
        {
          "query_string": {
            "query": "アゴ AND 優しい",
            "default_field": "*",
            "default_operator": "and"
          }
        }
      ]
    }
  }
}  

どんな不具合がでたか

検索ワードに「,"/!:()」とかあるとエラー 

確認したらまぁ400エラーになっとったね。

エラーメッセージはこんな感じ

{
  "error": {
    "root_cause": [
      {
        "type": "query_shard_exception",
        "reason": "Failed to parse query [アゴ出せ AND アゴ,/!:()]",
        "index_uuid": "AAlFgTt3R726dvUteFB93A",
        "index": "agodex"
      }
    ],
...

アゴ出せ 半角記号のパースエラー。 よくありそうなエラーですね。

パッと思いつく解決案

  1. 画面側で入力されたらエスケープするなり除外するなり
  2. サーバ側で取り除く
  3. Elasticsearchに投げるクエリのオプションとかで解決できないか探す

1はあまり無いですね。こーゆーのを画面だけに任せるのは心許ない
2は記号の種類を網羅したり、考えたりするのが嫌だったので後回し
3があれば1番楽かつ安心

探した結果 simple_query_stringを見つけた。

simple_query_stringとは

query_stringと似てますが、主な特徴として

  • クエリ文字列の無効な部分は無視される
  • よって、無効な構文に対してエラーを返さない
  • 機能はquery_stringより制限される

があります。

今回は無効な文字列を無視して、エラーを返さないってところがニーズに合ったので採用しました。

使い方

こんな感じ

GET agodex/_search
{
  "from": 0,
  "size": "50",
  "query": {
    "bool": {
      "must": [
        {
          "simple_query_string": {
            "query": "アゴ出せ アゴ,/!:()",
            "default_operator": "and"
          }
        }
      ]
    }
  }
}  

query_stringからの変更点として、"default_field": "*",が消えました。
代わりにfieldsという項目があるのですが、記述しなくてもデフォルトで "default_field": "*",と同じ動きをしてくれるみたいなので省いてます。
あとはquery内の 「AND」がなくなりました。


これも以下をみてもらうとわかりますが「+」に代るみたいです。"default_operator": "and"にしているの場合は省略可能。

Notes
Simple query string syntaxedit
The simple_query_string query supports the following operators:
+ signifies AND operation
| signifies OR operation
- negates a single token
" wraps a number of tokens to signify a phrase for searching
* at the end of a term signifies a prefix query
( and ) signify precedence
~N after a word signifies edit distance (fuzziness)
~N after a phrase signifies slop amount

感想

今回作ってたものはエラーで止めたくなかったのと、
簡単なクエリしか投げてなかったので、simple_query_stringを採用しました。

まぁ結局は作るもの次第なんだぜ。

f:id:agonosetaro:20200123141957p:plain:h200

スポンサーリンク