不正な形式のクエリ文字列は、OpenSearch が結果を返さない、またはエラーを通知せずに失敗する原因となり、構造が不適切なクエリは大規模データセットでの検索を遅延させます。本ページでは、解析エラーを回避するために遵守すべきクエリ構文ルールと、計算量を削減して応答時間を改善するための最適化手法について説明します。
クエリ構文ルール
以下のルールは、OpenSearch High-Performance Search Edition のすべてのクエリに適用されます。いずれかのルールに違反すると、解析エラーが発生するか、空の結果が返されます。
インデックスの指定
すべてのクエリは、名前付きのインデックスを対象とする必要があります。
query='mp3' # 以下と同等: query=default:'mp3'
query=default:'mp3' # インデックスを明示的に参照インデックスが指定されていない場合、OpenSearch は default インデックスを使用します。ただし、デフォルトインデックスが存在しない場合は、エラーが発生し、結果は返されません。予期しないフォールバック動作を回避するため、常にインデックス名を明示的に指定してください。
キーワードを一重引用符で囲む
クエリ文字列内のキーワードは、一重引用符 (') で囲む必要があります。
引用符で囲まれていないキーワードは解析エラーを引き起こし、結果は返されません。
# 不正 — エラーが返される
query=default:mp3
# 正しい形式
query=default:'mp3'特殊文字のエスケープ
引用符で囲まれたキーワード内では、次の 2 文字について特別な処理が必要です。
アポストロフィ (`'`) — バックスラッシュ (\) でエスケープするか、その文字を削除してください。
キーワード内にエスケープされていないアポストロフィが含まれていると、引用符で囲まれた文字列が中断され、解析エラーが発生します。
# 解析に失敗 — アポストロフィにより引用符で囲まれた文字列が中断される
query=default:'abc's efg'
# 正しい形式 — アポストロフィがエスケープされている
query=default:'abc\'s efg'バックスラッシュ (`\`) — 末尾のバックスラッシュは閉じ引用符をエスケープしてしまうため、解析エラーが発生します。キーワード内にリテラルとしてバックスラッシュを含める場合は、必ずエスケープしてください。
# エラー — バックスラッシュが閉じ引用符をエスケープしている
query=default:'abc\'
# 正しい形式 — リテラルのバックスラッシュがエスケープされている
query=default:'abc\\'query=default:'Beijing University' は、Beijing および University の両方を含むドキュメントを取得します。
パフォーマンスの最適化
検索パフォーマンスは、クエリに一致するドキュメント数に依存します。一致するドキュメントが少ないほど、計算量が減り、結果が高速に返されます。検索パイプラインの各段階で不要な作業を削減するため、以下の手法を適用してください。
フィールドフィルターをクエリ句内に移動
効果:高
フィールド値でのフィルター処理を行う場合、そのフィールドをインデックス化し、条件を query 句に移動します(filter を使用する代わりに)。
# 効率が低い — filter はクエリ実行後に実行され、インデックスによる高速化が利用できない
query=user_id:'123' && filter=type_id=1
# 効率が高い — 両方の条件がインデックスルックアップを利用する
query=user_id:'123' AND type_id:'1'query 句はインデックスによる高速化の恩恵を受けますが、filter 句はそうではありません。query 句内に条件を記述することで、OpenSearch はランキングや取得作業が始まる前に、インデックスを利用して一致しないドキュメントを早期に除外できます。
時間ベースのフィルタリングには範囲検索を使用
効果:高
filter を使用してタイムスタンプ範囲で大規模データセットをフィルタリングすると、OpenSearch が先行条件に一致するすべてのドキュメントをスキャンするため、処理が遅くなります。時間ベースのクエリでは、代わりにインデックス化されたタイムスタンプフィールドに対して範囲検索を使用してください。
# 遅い — OpenSearch は user_id=123 の 5,000 万件のレコードすべてをスキャンし、その中から範囲内の 1,000 件を検出
query=user_id:'123' && filter=time>"2016-09-16"
# 高速 — 範囲クエリがインデックスを利用して一致するレコードのみを直接取得
query=user_id:'123' AND index_timestamp:(1473955200000,)範囲検索は、インデックスフィールドがパイプラインの初期段階で大部分のドキュメントを除外できる場合に効果的であり、クエリ後の filter によるフルスキャンのコストを回避できます。
一致ドキュメント数の削減
効果:中
OpenSearch が取得するドキュメント数が少ないほど、結果が高速に返されます。
ヒット件数を減らすために、より具体的な用語やフィールド制約を追加してください。
デフォルトのページサイズは 20 件です。アプリケーションが実際に表示する件数よりも多くの結果を 1 ページあたりでリクエストしないでください。
必要なフィールドのみを返す
効果:中
ドキュメントが一致した後、OpenSearch は各結果の完全なレコードをフェッチします。使用しないフィールドをフェッチすると、特に結果ペイロードが大きい場合にレイテンシが増加します。
デフォルト表示フィールドを変更するか、fetch_fields パラメーターを設定して、アプリケーションが必要とするフィールドのみを指定してください。