milvus-logo
LFAI
フロントページへ
  • ユーザーガイド

テキストマッチ

Milvusのテキストマッチは、特定の用語に基づいた正確な文書検索を可能にします。この機能は主に特定の条件を満たすためのフィルタリング検索に使用され、クエリ結果を絞り込むためにスカラーフィルタリングを組み込むことができ、スカラー条件を満たすベクトル内の類似検索を可能にします。

テキストマッチは、マッチした文書の関連性をスコアリングすることなく、クエリー用語の正確な出現箇所を見つけることに重点を置いています。クエリー用語の意味や重要性に基づいて最も関連性の高い文書を検索したい場合は、Full Text Searchを使用することをお勧めします。

概要

MilvusはTantivyを統合し、転置インデックスと用語ベースのテキスト検索を実現しています。Milvusは各テキストエントリに対して、以下の手順でインデックスを作成します。

  1. アナライザー:アナライザは、入力テキストを個々の単語(トークン)にトークン化し、必要に応じてフィルタを適用することで処理します。これにより、Milvusはこれらのトークンに基づいたインデックスを構築することができる。

  2. インデックス作成:テキスト解析後、Milvusは各トークンを含む文書に対応付ける転置インデックスを作成します。

ユーザがテキストマッチを実行すると、転置インデックスがその用語を含む全ての文書を素早く検索するために使用される。これは、各文書を個別にスキャンするよりもはるかに高速です。

Text Match テキストマッチ

テキストマッチを有効にする

テキストマッチはVARCHAR フィールドタイプで機能します。これは基本的にmilvusの文字列データ型です。テキスト照合を有効にするには、enable_analyzerenable_match の両方をTrue に設定し、コレクションスキーマを定義する際にオプションでテキスト分析用のアナライザを設定します。

enable_analyzer およびenable_matchを設定します。

特定のVARCHAR フィールドのテキスト照合を有効にするには、フィールドスキーマを定義する際にenable_analyzerenable_match の両方のパラメータをTrue に設定します。これにより、Milvusはテキストをトークン化し、指定されたフィールドに対して転置インデックスを作成し、高速で効率的なテキストマッチを可能にします。

from pymilvus import MilvusClient, DataType

schema = MilvusClient.create_schema(auto_id=True, enable_dynamic_field=False)

schema.add_field(
    field_name='text', 
    datatype=DataType.VARCHAR, 
    max_length=1000, 
    enable_analyzer=True, # Whether to enable text analysis for this field
    enable_match=True # Whether to enable text match
)

import io.milvus.v2.common.DataType;
import io.milvus.v2.service.collection.request.AddFieldReq;
import io.milvus.v2.service.collection.request.CreateCollectionReq;

CreateCollectionReq.CollectionSchema schema = CreateCollectionReq.CollectionSchema.builder()
        .enableDynamicField(false)
        .build();

schema.addField(AddFieldReq.builder()
        .fieldName("text")
        .dataType(DataType.VarChar)
        .maxLength(1000)
        .enableAnalyzer(true)
        .enableMatch(true)
        .build());

const schema = [
  {
    name: "id",
    data_type: DataType.Int64,
    is_primary_key: true,
  },
  {
    name: "text",
    data_type: "VarChar",
    enable_analyzer: true,
    enable_match: true,
    max_length: 1000,
  },
  {
    name: "sparse",
    data_type: DataType.SparseFloatVector,
  },
];

export schema='{
        "autoId": true,
        "enabledDynamicField": false,
        "fields": [
            {
                "fieldName": "id",
                "dataType": "Int64",
                "isPrimary": true
            },
            {
                "fieldName": "text",
                "dataType": "VarChar",
                "elementTypeParams": {
                    "max_length": 1000,
                    "enable_analyzer": true,
                    "enable_match": true
                }
            },
            {
                "fieldName": "sparse",
                "dataType": "SparseFloatVector"
            }
        ]
    }'

オプション:アナライザーの設定

テキスト・マッチングのパフォーマンスと精度は、選択したアナライザーに依存します。異なるアナライザは様々な言語やテキスト構造に合わせて調整されているため、適切なアナライザを選択することで、特定のユースケースの検索結果に大きな影響を与えることができます。

デフォルトでは、Milvusはstandard アナライザーを使用します。このアナライザーは、空白と句読点に基づいてテキストをトークン化し、40文字以上のトークンを削除し、テキストを小文字に変換します。このデフォルト設定を適用するために追加のパラメータは必要ありません。詳細については、「標準」を参照してください。

別のアナライザが必要な場合は、analyzer_params パラメータを使用してアナライザを設定できます。例えば、英語のテキストを処理するためにenglish アナライザを適用する場合。

analyzer_params={
    "type": "english"
}

schema.add_field(
    field_name='text', 
    datatype=DataType.VARCHAR, 
    max_length=200, 
    enable_analyzer=True,
    analyzer_params=analyzer_params,
    enable_match=True, 
)

Map<String, Object> analyzerParams = new HashMap<>();
analyzerParams.put("type", "english");
schema.addField(AddFieldReq.builder()
        .fieldName("text")
        .dataType(DataType.VarChar)
        .maxLength(200)
        .enableAnalyzer(true)
        .analyzerParams(analyzerParams)
        .enableMatch(true)
        .build());

const schema = [
  {
    name: "id",
    data_type: DataType.Int64,
    is_primary_key: true,
  },
  {
    name: "text",
    data_type: "VarChar",
    enable_analyzer: true,
    enable_match: true,
    max_length: 1000,
    analyzer_params: { type: 'english' },
  },
  {
    name: "sparse",
    data_type: DataType.SparseFloatVector,
  },
];

export schema='{
        "autoId": true,
        "enabledDynamicField": false,
        "fields": [
            {
                "fieldName": "id",
                "dataType": "Int64",
                "isPrimary": true
            },
            {
                "fieldName": "text",
                "dataType": "VarChar",
                "elementTypeParams": {
                    "max_length": 200,
                    "enable_analyzer": true,
                    "enable_match": true,
                    "analyzer_params": {"type": "english"}
                }
            },
            {
                "fieldName": "my_vector",
                "dataType": "FloatVector",
                "elementTypeParams": {
                    "dim": "5"
                }
            }
        ]
    }'

Milvusは他にも様々な言語やシナリオに適したアナライザを提供しています。詳細については、「概要」を参照してください。

テキストマッチの使用

コレクションスキーマでVARCHARフィールドのテキストマッチを有効にすると、TEXT_MATCH 式を使用してテキストマッチを実行できます。

TEXT_MATCH 式の構文

TEXT_MATCH 式を使用して、検索するフィールドと用語を指定します。その構文は以下のとおりです。

TEXT_MATCH(field_name, text)

  • field_name:検索するVARCHARフィールドの名前。

  • text:検索する条件。複数の用語は、言語や設定されている解析器に応じて、スペースやその他の適切な区切り文字で区切ることができます。

デフォルトでは、TEXT_MATCHORマッチング・ロジックを使用します。つまり、指定された用語のいずれかを含む文書を返します。たとえば、text フィールドにmachine またはdeep という用語を含むドキュメントを検索するには、次の式を使用します。

filter = "TEXT_MATCH(text, 'machine deep')"
String filter = "TEXT_MATCH(text, 'machine deep')";
const filter = "TEXT_MATCH(text, 'machine deep')";
export filter="\"TEXT_MATCH(text, 'machine deep')\""

論理演算子を使用して複数のTEXT_MATCH 式を組み合わせ、ANDマッチングを実行することもできます。

  • text フィールドにmachinedeep の両方を含む文書を検索するには、次の式を使用します。

    filter = "TEXT_MATCH(text, 'machine') and TEXT_MATCH(text, 'deep')"
    
    String filter = "TEXT_MATCH(text, 'machine') and TEXT_MATCH(text, 'deep')";
    
    const filter = "TEXT_MATCH(text, 'machine') and TEXT_MATCH(text, 'deep')"
    
    export filter="\"TEXT_MATCH(text, 'machine') and TEXT_MATCH(text, 'deep')\""
    
  • machinelearning の両方を含み、text フィールドにdeep を含まない文書を検索するには、以下の式を使用する:

    filter = "not TEXT_MATCH(text, 'deep') and TEXT_MATCH(text, 'machine') and TEXT_MATCH(text, 'learning')"
    
    String filter = "not TEXT_MATCH(text, 'deep') and TEXT_MATCH(text, 'machine') and TEXT_MATCH(text, 'learning')";
    
    const filter = "not TEXT_MATCH(text, 'deep') and TEXT_MATCH(text, 'machine') and TEXT_MATCH(text, 'learning')";
    
    export filter="\"not TEXT_MATCH(text, 'deep') and TEXT_MATCH(text, 'machine') and TEXT_MATCH(text, 'learning')\""
    

テキスト・マッチによる検索

テキスト・マッチをベクトル類似性検索と組み合わせて使うことで、検索範囲を狭め、検索パフォーマンスを向上させることができる。ベクトル類似検索の前にテキストマッチを使ってコレクションをフィルタリングすることで、検索が必要なドキュメントの数を減らすことができ、結果的にクエリー時間を短縮することができます。

この例では、filter 式は、指定された用語keyword1 またはkeyword2 に一致する文書のみを含むように検索結果をフィルタリングします。その後、ベクトル類似性検索は、このフィルタリングされた文書のサブセットに対して実行されます。

# Match entities with `keyword1` or `keyword2`
filter = "TEXT_MATCH(text, 'keyword1 keyword2')"

# Assuming 'embeddings' is the vector field and 'text' is the VARCHAR field
result = MilvusClient.search(
    collection_name="YOUR_COLLECTION_NAME", # Your collection name
    anns_field="embeddings", # Vector field name
    data=[query_vector], # Query vector
    filter=filter,
    search_params={"params": {"nprobe": 10}},
    limit=10, # Max. number of results to return
    output_fields=["id", "text"] # Fields to return
)

String filter = "TEXT_MATCH(text, 'keyword1 keyword2')";

SearchResp searchResp = client.search(SearchReq.builder()
        .collectionName("YOUR_COLLECTION_NAME")
        .annsField("embeddings")
        .data(Collections.singletonList(queryVector)))
        .filter(filter)
        .topK(10)
        .outputFields(Arrays.asList("id", "text"))
        .build());
// Match entities with `keyword1` or `keyword2`
const filter = "TEXT_MATCH(text, 'keyword1 keyword2')";

// Assuming 'embeddings' is the vector field and 'text' is the VARCHAR field
const result = await client.search(
    collection_name: "YOUR_COLLECTION_NAME", // Your collection name
    anns_field: "embeddings", // Vector field name
    data: [query_vector], // Query vector
    filter: filter,
    params: {"nprobe": 10},
    limit: 10, // Max. number of results to return
    output_fields: ["id", "text"] //Fields to return
);
export filter="\"TEXT_MATCH(text, 'keyword1 keyword2')\""

export CLUSTER_ENDPOINT="http://localhost:19530"
export TOKEN="root:Milvus"

curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/search" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d '{
    "collectionName": "demo2",
    "annsField": "my_vector",
    "data": [[0.19886812562848388, 0.06023560599112088, 0.6976963061752597, 0.2614474506242501, 0.838729485096104]],
    "filter": '"$filter"',
    "searchParams": {
        "params": {
            "nprobe": 10
        }
    },
    "limit": 3,
    "outputFields": ["text","id"]
}'

テキストマッチによるクエリー

テキストマッチは、クエリー操作のスカラーフィルタリングにも使うことができる。query() メソッドのexpr パラメータにTEXT_MATCH 式を指定することで、指定した条件にマッチするドキュメントを取得することができます。

以下の例は、text フィールドがkeyword1keyword2 の両方の用語を含むドキュメントを検索します。

# Match entities with both `keyword1` and `keyword2`
filter = "TEXT_MATCH(text, 'keyword1') and TEXT_MATCH(text, 'keyword2')"

result = MilvusClient.query(
    collection_name="YOUR_COLLECTION_NAME",
    filter=filter, 
    output_fields=["id", "text"]
)

String filter = "TEXT_MATCH(text, 'keyword1') and TEXT_MATCH(text, 'keyword2')";

QueryResp queryResp = client.query(QueryReq.builder()
        .collectionName("YOUR_COLLECTION_NAME")
        .filter(filter)
        .outputFields(Arrays.asList("id", "text"))
        .build()
);
// Match entities with both `keyword1` and `keyword2`
const filter = "TEXT_MATCH(text, 'keyword1') and TEXT_MATCH(text, 'keyword2')";

const result = await client.query(
    collection_name: "YOUR_COLLECTION_NAME",
    filter: filter, 
    output_fields: ["id", "text"]
)
export filter="\"TEXT_MATCH(text, 'keyword1') and TEXT_MATCH(text, 'keyword2')\""

export CLUSTER_ENDPOINT="http://localhost:19530"
export TOKEN="root:Milvus"

curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/query" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d '{
    "collectionName": "demo2",
    "filter": '"$filter"',
    "outputFields": ["id", "text"]
}'

注意点

  • フィールドのテキスト・マッチを有効にすると、転置インデックスが作成され、 ストレージ・リソースが消費されます。この機能を有効にするかどうかは、テキストのサイズや一意なトークン、使用する解析器によって異なるので、ストレージへの影響を考慮してください。

  • スキーマでアナライザを定義すると、その設定はそのコレクションに対して永続的になります。異なるアナライザがよりニーズに合うと判断した場合は、既存のコレクションを削除し、希望するアナライザ設定で新しいコレクションを作成することを検討してください。

  • filter 式のエスケープ規則:

    • 式内の二重引用符または一重引用符で囲まれた文字は、文字列定数として解釈されます。文字列定数にエスケープ文字が含まれる場合、エスケープ文字はエスケープシーケンスで表現しなければならない。例えば、\ を表すには\\ を、タブを表すには\\t を、改行を表すには\t を、\\n を使用する。
    • 'It\\'s milvus'文字列定数が一重引用符で囲まれている場合、定数内の一重引用符は\\' と表現し、二重引用符は" または\\" と表現する。
    • "He said \\"Hi\\""文字列定数が二重引用符で囲まれている場合、定数内の二重引用符は\\" 、一重引用符は' または\\' のように表す。

翻訳DeepL

Try Managed Milvus for Free

Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.

Get Started
フィードバック

このページは役に立ちましたか ?