メインコンテンツまでスキップ

パターンマッチング

エージェント型検索アプリケーションでは、ベクトル検索と grep 形式のパターンマッチングがしばしば互いを補完します。ベクトル検索は意味的に関連するエンティティを取得し、パターンマッチングはエラーコード、ログプレフィックス、メールドメイン、URL パス、識別子などの正確な文字列構造によってその結果を絞り込みます。

Zilliz Cloud では、これらのパターン制約をスカラーフィルターで表現できます。単純なワイルドカードマッチングには LIKE を、RE2 正規表現には =~ または !~ を使用します。これらのフィルターは query、search、ハイブリッド検索と組み合わせることができます。

📘Notes

このページでは、query、search、ハイブリッド検索で使用されるスカラーフィルター式でのパターンマッチングについて説明します。これらの式はフィールド値を評価し、アナライザーが生成するトークンを変更しません。テキスト分析中にトークンをフィルタリングする場合は、Regex Analyzer Filter を参照してください。

パターンマッチング式は filter パラメーターに記述します。たとえば、次のクエリは E1001 などのエラーコードを含むログメッセージに一致します:

python
from pymilvus import MilvusClient

client = MilvusClient(uri="YOUR_CLUSTER_ENDPOINT")

res = client.query(
collection_name="log_events",
filter='message =~ "E[0-9]{4}"',
output_fields=["message", "severity"],
)

このページの例では、filter に割り当てる式に焦点を当てています。query、search、ハイブリッド検索など、スカラーフィルターを受け入れる Zilliz Cloud の操作では、同じフィルター式構文を使用できます。

📘Notes

フィルター式の左辺のリテラルには、以下の例で使用されている message、email などのコレクションフィールド名、または filter = 'struct[0][subfield] =~ "E[0-9]{4}"' のように特定の要素インデックスにある StructArray サブフィールドの名前を指定できます。

StructArray フィールドでのスカラーフィルタリングの詳細は、StructArray Operators を参照してください。

サポートされているフィールド型​

パターンマッチングは文字列値で利用できます。

対象LIKE正規表現 =~ / !~備考
VARCHAR フィールドはいはい文字列フィールドに対するパターンマッチングの一般的な対象です。
VARCHAR キャスト型の JSON パスはいはい肯定的な一致には、JSON パスの値が文字列である必要があります。高速化のために JSON パスにインデックスを作成する場合は、json_cast_type="varchar" を設定します。
ARRAY<VARCHAR> 要素はいはいtags[0] など、インデックスで特定の要素を指定して一致させます。パターンマッチングはすべての要素をスキャンしません。指定したインデックスの要素にのみ適用されます。
数値、Boolean、ベクトル、TEXT、その他の VARCHAR 以外の対象いいえいいえパターンマッチングは、VARCHAR 値、文字列に解決される JSON パス、またはインデックスが作成された ARRAY<VARCHAR> 要素でのみ利用できます。

LIKE または正規表現の選択​

必要なパターンを表現する最も単純な演算子を選択してください。

文字列の完全一致が必要な場合は、パターンマッチングではなく == の使用をお勧めします。フィルターでパターンに一致させる必要がある場合にのみ、LIKE または正規表現を使用してください。

要件推奨される演算子例説明
文字列の完全等価==status == "active"文字列 active との完全一致です。
単純な前方一致LIKEname LIKE "Prod%"Prod で始まる文字列に一致します。
単純な後方一致LIKEfilename LIKE "%.json".json で終わる文字列に一致します。
単純な部分一致LIKEdescription LIKE "%vector database%"文字列内の任意の位置に vector database を含む値に一致します。
構造化されたコードまたは固定長パターンとの一致=~code =~ "E[0-9]{4}"E1001 など、E の後に 4 桁の数字が続く文字列に大文字と小文字を区別して一致します。
大文字と小文字を区別しないパターンマッチング=~ と (?i)message =~ "(?i)error"error、ERROR、その他の大文字と小文字のバリエーションに一致します。
正規表現パターンに一致する値を除外!~message !~ "^DEBUG"DEBUG で始まる文字列を除外します。

単純なワイルドカードマッチングには LIKE を使用します。パターンに文字クラス、繰り返し、error|failed などの選択、アンカー、または大文字と小文字を区別しないマッチングが必要な場合は、正規表現を使用します。

LIKE の使用​

LIKE 演算子は、文字列値に対する単純なワイルドカードマッチングに使用します。次のワイルドカードのみをサポートしています:

ワイルドカード説明
%0 個以上の文字に一致します。
_ちょうど 1 文字に一致します。

一般的な LIKE パターン​

% と _ の位置を使用して、一致する文字列内で固定テキストが現れる位置を制御します。

要件パターンフィルターの例
プレフィックスで始まるProd%filter = 'name LIKE "Prod%"'
サフィックスで終わる%.jsonfilter = 'filename LIKE "%.json"'
部分文字列を含む%vector%filter = 'description LIKE "%vector%"'
固定位置の 1 文字に一致するAB_%filter = 'code LIKE "AB_%"'

LIKE のマッチング動作​

前方一致、後方一致、部分一致、固定位置の 1 文字一致には LIKE を使用します。LIKE は、[0-9] などの文字クラス、error|failed などの選択、{4} などの繰り返し回数、^ や $ などのアンカー、(?i) などの大文字と小文字を区別しないフラグをサポートしていません。これらのパターンには正規表現を使用してください。

文字列全体の完全等価には == を使用します。フィルターでワイルドカードマッチングが必要な場合にのみ、LIKE を使用してください。

LIKE パターンでのワイルドカードのエスケープ​

LIKE パターンでは、% は 0 文字以上に一致し、_ はちょうど 1 文字に一致します。%、_、または \ をリテラルとして一致させるには、バックスラッシュ(\)でその文字をエスケープします:

  • name LIKE r"\%" はリテラル値 % に一致します。
  • name LIKE r"\_%" はリテラル _ で始まる値に一致します。
  • name LIKE r"\\%" はリテラルのバックスラッシュで始まる値に一致します。

r"..." または r'...' と記述する raw 文字列リテラルでは、Zilliz Cloud のフィルター式内でバックスラッシュがそのまま保持されます。バックスラッシュを含む LIKE および正規表現パターンには、これらの使用をお勧めします。raw 文字列を使用しない場合、通常の文字列リテラルはパターンが評価される前にエスケープシーケンスを処理するため、より多くのバックスラッシュが必要になることがあります。

正規表現の使用​

Public Preview

パターンに文字クラス、繰り返し、選択、アンカー、または大文字と小文字を区別しないマッチングなどの正規表現機能が必要な場合は、正規表現フィルターを使用します。Zilliz Cloud は文字列値に RE2 正規表現を適用します。

=~ または !~ の右辺は文字列リテラルである必要があります。

演算子意味例
=~正規表現パターンを満たす値に一致します。filter = 'message =~ "E[0-9]{4}"'
!~正規表現パターンを満たす値を除外します。filter = 'message !~ "^DEBUG"'

raw 文字列リテラルの使用​

バックスラッシュを含む正規表現パターンには、raw 文字列リテラルの使用をお勧めします。r"..." または r'...' と記述する raw 文字列では、バックスラッシュが正規表現エンジンにそのまま渡されます。これにより、通常の文字列リテラルで必要な追加のエスケープを回避できます。

例:

python
filter = r'filename =~ r"\.json$"'

これは、.json で終わる文字列(report.json など)に一致します。

Zilliz Cloud のフィルター式で raw 文字列を使用しない場合、通常の文字列リテラルは正規表現パターンが評価される前にエスケープシーケンスを処理します。そのため、エスケープされたリテラル文字は、ホスト言語の文字列で追加のバックスラッシュが必要になる場合があります。

一般的な正規表現パターン​

次の例では、Zilliz Cloud のフィルター式で一般的な RE2 構文を使用しています。完全な正規表現構文については、RE2 構文リファレンスを参照してください。

要件パターンフィルターの例
リテラルテキストを含むerrorfilter = 'message =~ "error"'
プレフィックスで始まる^ERRfilter = 'code =~ "^ERR"'
サフィックスで終わる\.json$filter = 'filename =~ "\\.json$"'
数字のシーケンスに一致する[0-9]+filter = 'message =~ "[0-9]+"'
固定桁数の数字に一致する[0-9]{4}filter = 'code =~ "[0-9]{4}"'
メールドメインに一致する@example\.com$filter = 'email =~ "@example\\.com$"'
大文字と小文字を区別せずに一致する(?i)errorfilter = 'message =~ "(?i)error"'
文字列全体に一致する^prod-[0-9]+$filter = 'name =~ "^prod-[0-9]+$"'

複数の単語のいずれかに一致させるには、| による選択を使用します:

python
filter = 'message =~ "error|failed|timeout"'

正規表現のメタ文字をリテラルとして一致させる場合は、正規表現パターン内でそれらをエスケープします。たとえば、リテラルのドット(正規表現では \.)に一致させるには、Python、Java、Go、または Node.js のソース文字列で \\. と記述します:

python
filter = 'email =~ "@gmail\\.com$"'

注記:Zilliz Cloud の正規表現フィルターは RE2 構文に従います。正規表現パターンが RE2 でサポートされていない構文を使用している場合、またはその他の理由で無効な場合、Zilliz Cloud はフィルター式を拒否します。正規表現のメタ文字、フラグ、マッチング動作の詳細については、RE2 構文リファレンスを参照してください。

マッチング動作​

部分文字列マッチング

Zilliz Cloud の正規表現マッチングでは、部分文字列のセマンティクスが使用されます。パターンはフィールド値全体に一致する必要はありません。たとえば、次のフィルターは E1001 と failed with E1001 after retry の両方に一致します:

python
filter = 'message =~ "E[0-9]{4}"'

フィールド値全体に一致させるには、^ と $ のアンカーを使用します:

python
# Match only values that are exactly E followed by four digits
filter = 'code =~ "^E[0-9]{4}$"'

Nullable な VARCHAR フィールド

正規表現フィルターは null 値に一致しません。これは =~ と !~ の両方に当てはまります。正規表現パターンを除外しつつ null 値を保持する場合は、OR field IS NULL を明示的に追加します:

python
filter = 'message !~ "^DEBUG" OR message IS NULL'

JSON パス

JSON パスでは、パスが存在しない場合、null の場合、または文字列以外の値に解決される場合、正規表現フィルターの動作が異なります:

フィルター欠落/null/non-string 値を含むか備考
json_field["path"] =~ "pattern"いいえ正規表現パターンを満たす文字列値にのみ一致します。
json_field["path"] !~ "pattern"はいパスが欠落している、null である、文字列以外である、または正規表現パターンに一致しない文字列であるエンティティを返します。

インデックスによるパターンマッチングの高速化​

Zilliz Cloud は、VARCHAR フィールドまたは JSON 文字列パスに対する LIKE および正規表現フィルターと併用できるいくつかのインデックスタイプを文字列フィールドでサポートしています。たとえば、NGRAM、STL_SORT、INVERTED、BITMAP などです。パターンマッチングはインデックスなしでも機能しますが、インデックスによって大規模なデータセットでのパフォーマンスを向上できます。

インデックスの有効性は、パターン式、Zilliz Cloud が固定のリテラル部分文字列を抽出できるかどうか、および対象フィールドのカーディナリティと分散によって決まります。name LIKE "Prod%" などの前方一致形式のパターンは、description LIKE "%vector%" や filename LIKE "%.json" などの中間一致または後方一致のパターンとは異なるインデックス戦略の恩恵を受ける場合があります。

次の表を出発点として使用し、その後、実際のワークロードでベンチマークしてください:

パターンまたはデータ特性検討するインデックス備考
message =~ "error.*timeout" や message LIKE "%database%" など、固定のリテラル部分文字列を含むNGRAMZilliz Cloud がパターンから意味のあるリテラル部分文字列を抽出できる場合に役立ちます。詳細は、NGRAM を参照してください。
前方一致、完全一致、または等価に近い文字列フィルター。特にカーディナリティが低から中程度のフィールドSTL_SORT、INVERTED、または BITMAPフィールドに重複する値がある場合、またはフィルターが完全一致に近い場合に、より効果的となることがあります。詳細は、STL_SORT、INVERTED、および BITMAP を参照してください。
固定リテラルを含まない正規表現パターン、または文字クラス、短いトークン、ワイルドカードが中心のパターンインデックスによる高速化に依存する前にベンチマークするこれらのパターンはインデックスの選択性が限定的であり、より広範なスキャンにフォールバックする可能性があります。