ユースケースに適したアナライザーを選択する
このガイドでは、Zilliz Cloud のテキストコンテンツに最適な アナライザー を選択して構成する方法について説明します。
実践的な意思決定に焦点を当て、どのアナライザーを使用するか、いつカスタマイズするか、構成をどのように検証するかを説明します。アナライザーのコンポーネントとパラメーターの背景については、アナライザーの概要 を参照してください。
クイックコンセプト:アナライザーの仕組み
アナライザーはテキストデータを処理し、全文検索(BM25 ベース)、フレーズ一致、テキスト一致 などの機能で検索できるようにします。2 段階のパイプラインを通じて、生のテキストを個別の検索可能なトークンに変換します。

-
トークン化(必須): この最初の段階では、トークナイザー を適用して、連続するテキスト文字列をトークンと呼ばれる個別の意味のある単位に分割します。トークン化の方法は、言語とコンテンツの種類によって大きく異なる場合があります。
-
トークンフィルタリング(オプション): トークン化の後、フィルター を適用してトークンを変更、削除、または絞り込みます。これらの操作には、すべてのトークンを小文字に変換する、一般的で意味のない単語(ストップワードなど)を削除する、単語を語幹の形に縮小する(ステミング)などがあります。
例:
Input: "Hello World!"
1. Tokenization → ["Hello", "World", "!"]
2. Lowercase & Punctuation Filtering → ["hello", "world"]
アナライザーの選択が重要な理由
選択するアナライザーは、検索品質と関連性に直接影響します。
不適切なアナライザーを使用すると、トークン化の不足または過剰、検索語の欠落、無関係な結果などが発生する可能性があります。
問題 | 症状 | 例(入力と出力) | 原因(不適切なアナライザー) | 解決策(適切なアナライザー) |
|---|---|---|---|---|
トークン化の過剰 | 技術用語、識別子、URL が正しく分割されない |
|
|
|
トークン化の不足 | 複数の単語からなるフレーズが 1 つのトークンとして扱われる |
|
|
|
言語の不一致 | 外国語の結果が意味をなさない | 中国語テキスト: |
|
|
入力方式の不一致 | ユーザーはピンインを入力しますが、インデックス付けされたテキストは中国語の文字を使用します。 | 中国語テキスト: | 中国語の文字のトークンのみを出力するアナライザー |
ステップ 1:アナライザーを選択する必要がありますか?
テキスト取得機能(全文検索、フレーズ一致、テキスト一致 など)を使用していて、アナライザーを明示的に指定していない場合、Zilliz Cloud は standard アナライザー を自動的に適用します。
standard アナライザーの動作:
-
スペースと句読点でテキストを分割します
-
すべてのトークンを小文字に変換します
変換例:
Input: "The Milvus vector database is built for scale!"
Output: ['the', 'milvus', 'vector', 'database', 'is', 'built', 'for', 'scale']
ステップ 2:standard アナライザーがニーズを満たすか確認する
この表を使用して、デフォルトの standardアナライザー がニーズを満たすかをすばやく確認します。満たさない場合は、別のパスを選択 する必要があります。
| コンテンツの種類 | standard アナライザーで問題ないか | 理由 | 必要な対応 |
| 英語のブログ投稿 | はい | デフォルトの動作で十分です。 | デフォルトを使用します(構成は不要です)。 |
| 中国語のドキュメント | いいえ | 中国語の単語にはスペースがなく、1 つのトークンとして扱われます。 | 組み込みの chinese アナライザーを使用します。 |
| 技術ドキュメント | いいえ | C++ のような用語から句読点が削除されます。 | whitespace トークナイザーと alphanumonly フィルターを備えたカスタムアナライザーを作成します。 |
| フランス語/Spanish テキストなどのスペース区切り言語 | ⚠️ 場合による | アクセント付き文字(café と cafe)が一致しない場合があります。 | より良い結果を得るには、asciifolding を備えたカスタムアナライザーをお勧めします。 |
| 多言語または不明な言語 | いいえ | standard アナライザーには、異なる文字セットとトークン化ルールを処理するために必要な言語固有のロジックがありません。 | Unicode を考慮したトークン化を行うには、icu トークナイザーを備えたカスタムアナライザーを使用します。
または、多言語アナライザー や 言語識別子 を構成して、多言語コンテンツをより正確に処理することを検討してください。 |
ステップ 3:パスを選択する
デフォルトの standard アナライザー が不十分な場合は、次の 2 つのパスのいずれかを選択します:
-
パス A – 組み込みアナライザーを使用する(すぐに使用可能、言語固有)
-
パス B – カスタムアナライザーを作成する(トークナイザー + 一連のフィルターを手動で定義する)
パス A:組み込みアナライザーを使用する
組み込みアナライザーは、一般的な言語向けに事前構成されたソリューションです。デフォルトの standard アナライザーが完全に適合しない場合に、最も簡単に開始できる方法です。
利用可能な組み込みアナライザー
アナライザー | 言語サポート | コンポーネント | 注意 |
|---|---|---|---|
スペース区切りの言語の大半(英語、フランス語、ドイツ語、スペイン語など) |
| 初期テキスト処理向けの汎用アナライザーです。単一言語のシナリオでは、言語固有のアナライザー( | |
Dedicated アナライザーは英語専用で、英語の意味マッチングを改善するためにステミングとストップワードの削除を適用します。 |
|
| |
中国語 |
| 現在、デフォルトで簡体字中国語の辞書を使用しています。 |
実装例
組み込みアナライザーを使用するには、フィールドスキーマを定義するときに analyzer_params でそのタイプを指定するだけです。
- Python
- Java
- Go
- Rust
- C++
- NodeJS
- cURL
# Using built-in English analyzer
analyzer_params = {
"type": "english"
}
# Applying analyzer config to target VARCHAR field in your collection schema
schema.add_field(
field_name='text',
datatype=DataType.VARCHAR,
max_length=200,
enable_analyzer=True,
analyzer_params=analyzer_params,
)
import io.milvus.v2.common.DataType;
import io.milvus.v2.service.collection.request.AddFieldReq;
import java.util.HashMap;
import java.util.Map;
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)
.build());
import "github.com/milvus-io/milvus/client/v3/entity"
analyzerParams := map[string]any{"type": "english"}
schema.WithField(entity.NewField().
WithName("text").
WithDataType(entity.FieldTypeVarChar).
WithMaxLength(200).
WithEnableAnalyzer(true).
WithAnalyzerParams(analyzerParams))
use milvus::v2::prelude::*;
use serde_json::json;
let analyzer_params = serde_json::json!({"type": "english"});
let schema = CollectionSchema::new().add_field(FieldSchema::new()
.name("text")
.data_type(DataType::VarChar)
.max_length(200)
.enable_analyzer(true)
.analyzer_params(analyzer_params));
nlohmann::json analyzer_params = {{"type", "english"}};
schema->AddField(milvus::FieldSchema("text", milvus::DataType::VARCHAR)
.WithMaxLength(200)
.EnableAnalyzer(true)
.WithAnalyzerParams(analyzer_params));
import { DataType } from "@zilliz/milvus2-sdk-node";
const analyzer_params = { type: "english" };
const schema = [
{
name: "text",
data_type: DataType.VarChar,
max_length: 200,
enable_analyzer: true,
analyzer_params,
},
];
export textField='{
"fieldName": "text",
"dataType": "VarChar",
"elementTypeParams": {
"max_length": 200,
"enable_analyzer": true,
"analyzer_params": "{\"type\":\"english\"}"
}
}'
パス B:カスタムアナライザーを作成する
組み込みのオプションを使用するだけではニーズを満たせない場合は、トークナイザーと一連のフィルターを組み合わせてカスタムアナライザーを作成できます。これにより、テキスト処理パイプラインを完全に制御できます。
ステップ 1:言語に基づいてトークナイザーを選択する
コンテンツの主要言語に基づいてトークナイザーを選択します:
西ヨーロッパ言語
スペース区切りの言語には、次のオプションがあります:
トークナイザー | 動作 | 最適な用途 | 例 |
|---|---|---|---|
スペースと句読点に基づいてテキストを分割します | 一般的なテキスト、混在した句読点 |
| |
空白文字のみで分割します | 前処理済みのコンテンツ、ユーザーが整形したテキスト |
|
東アジア言語
辞書ベースの言語では、適切な単語分割のために専用のトークナイザーが必要です:
中国語
トークナイザー | 動作 | 最適な用途 | 例 |
|---|---|---|---|
インテリジェントアルゴリズムを使用した中国語辞書ベースの分割 | 中国語コンテンツにお勧め - 辞書とインテリジェントアルゴリズムを組み合わせ、中国語向けに特別に設計されています。 |
| |
中国語辞書(cc-cedict)を使用した純粋な辞書ベースの形態素解析 |
|
|
日本語と韓国語
言語 | トークナイザー | 辞書オプション | 最適な用途 | 例 |
|---|---|---|---|---|
日本語 | ipadic(汎用)、ipadic-neologd(現代用語)、unidic(学術) | 固有名詞を処理する形態素解析 |
| |
韓国語 | 韓国語の形態素解析 |
|
多言語または不明な言語
言語が予測できない、またはドキュメント内で混在しているコンテンツの場合:
トークナイザー | 動作 | 最適な用途 | 例 |
|---|---|---|---|
Unicode 対応のトークン化(International Components for Unicode) | 混在した文字体系、不明な言語、または単純なトークン化で十分な場合 |
|
icu を使用する場合:
-
言語の識別が現実的でない混在言語。
-
コンテンツに主要言語があり、全体的な意味への寄与が少ない外来語が時々含まれる場合(例: 英語のテキストに日本語やフランス語のブランド名や技術用語が散発的に含まれる場合)。
代替のアプローチ: 多言語コンテンツをより正確に処理するには、多言語アナライザーまたは言語識別子の使用を検討してください。詳細については、多言語アナライザー または 言語識別子 を参照してください。
ステップ 2:精度向上のためにフィルターを追加する
トークナイザーを選択したら、特定の検索要件とコンテンツの特性に基づいてフィルターを適用します。
一般的に使用されるフィルター
これらのフィルターは、大半のスペース区切り言語の構成(英語、フランス語、ドイツ語、スペイン語など)に不可欠であり、検索品質を大幅に向上させます:
フィルター | 動作 | 使用する場合 | 例 |
|---|---|---|---|
すべてのトークンを小文字に変換します | 汎用 - 大文字と小文字の区別があるすべての言語に適用されます |
| |
単語をその語幹の形に縮小します | 単語の活用がある言語(英語、フランス語、ドイツ語など) | 英語の場合:
| |
一般的で意味のない単語を削除します | ほとんどの言語 - スペース区切り言語では特に効果的です |
|
東アジアの言語(中国語、日本語、韓国語など)では、代わりに言語固有のフィルターに焦点を当ててください。これらの言語は通常、テキスト処理に異なるアプローチを使用しており、ステミングによる大きな利点は得られない可能性があります。
テキスト正規化フィルター
これらのフィルターはテキストのばらつきを標準化して、一致の一貫性を向上させます:
フィルター | 動作 | 使用する場合 | 例 |
|---|---|---|---|
アクセント付き文字を ASCII の同等文字に変換します | 国際的なコンテンツ、ユーザー生成コンテンツ |
|
トークンフィルタリング
文字の内容または長さに基づいて、保持するトークンを制御します:
フィルター | 動作 | 使用する場合 | 例 |
|---|---|---|---|
単独の句読点トークンを削除します |
|
| |
文字と数字のみを保持します | 技術コンテンツ、クリーンなテキスト処理 |
| |
指定した長さの範囲外のトークンを削除します | ノイズ(過度に長いトークン)をフィルタリングします |
| |
カスタムパターンベースのフィルタリング | ドメイン固有のトークン要件 |
|
言語固有のフィルター
これらのフィルターは特定の言語特性を処理します:
フィルター | 言語 | 動作 | 例 |
|---|---|---|---|
ドイツ語 | 複合語を検索可能なコンポーネントに分割します |
| |
中国語 | 中国語の文字 + 英数字を保持します |
| |
中国語 | 中国語の文字のみを保持します |
| |
中国語 | 中国語トークンに対してピンイン形式のトークンを出力します |
|
ステップ 3:組み合わせて実装する
カスタムアナライザーを作成するには、analyzer_params 辞書でトークナイザーとフィルターのリストを定義します。フィルターはリストに記載された順序で適用されます。
- Python
- Java
- Go
- Rust
- C++
- NodeJS
- cURL
# Example: A custom analyzer for technical content
analyzer_params = {
"tokenizer": "whitespace",
"filter": ["lowercase", "alphanumonly"]
}
# Applying analyzer config to target VARCHAR field in your collection schema
schema.add_field(
field_name='text',
datatype=DataType.VARCHAR,
max_length=200,
enable_analyzer=True,
analyzer_params=analyzer_params,
)
import io.milvus.v2.common.DataType;
import io.milvus.v2.service.collection.request.AddFieldReq;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
Map<String, Object> analyzerParams = new HashMap<>();
analyzerParams.put("tokenizer", "whitespace");
analyzerParams.put("filter", Arrays.asList("lowercase", "alphanumonly"));
schema.addField(AddFieldReq.builder()
.fieldName("text")
.dataType(DataType.VarChar)
.maxLength(200)
.enableAnalyzer(true)
.analyzerParams(analyzerParams)
.build());
import "github.com/milvus-io/milvus/client/v3/entity"
analyzerParams := map[string]any{
"tokenizer": "whitespace",
"filter": []any{"lowercase", "alphanumonly"},
}
schema.WithField(entity.NewField().
WithName("text").
WithDataType(entity.FieldTypeVarChar).
WithMaxLength(200).
WithEnableAnalyzer(true).
WithAnalyzerParams(analyzerParams))
use milvus::v2::prelude::*;
use serde_json::json;
let analyzer_params = serde_json::json!({
"tokenizer": "whitespace",
"filter": ["lowercase", "alphanumonly"]
});
let schema = CollectionSchema::new().add_field(FieldSchema::new()
.name("text")
.data_type(DataType::VarChar)
.max_length(200)
.enable_analyzer(true)
.analyzer_params(analyzer_params));
nlohmann::json analyzer_params = {
{"tokenizer", "whitespace"},
{"filter", {"lowercase", "alphanumonly"}}
};
schema->AddField(milvus::FieldSchema("text", milvus::DataType::VARCHAR)
.WithMaxLength(200)
.EnableAnalyzer(true)
.WithAnalyzerParams(analyzer_params));
import { DataType } from "@zilliz/milvus2-sdk-node";
const analyzer_params = {
tokenizer: "whitespace",
filter: ["lowercase", "alphanumonly"],
};
const schema = [
{
name: "text",
data_type: DataType.VarChar,
max_length: 200,
enable_analyzer: true,
analyzer_params,
},
];
export textField='{
"fieldName": "text",
"dataType": "VarChar",
"elementTypeParams": {
"max_length": 200,
"enable_analyzer": true,
"analyzer_params": "{\"tokenizer\":\"whitespace\",\"filter\":[\"lowercase\",\"alphanumonly\"]}"
}
}'
最後:run_analyzer でテストする
コレクションに適用する前に、必ず構成を検証してください:
- Python
- Java
- Go
- Rust
- C++
- NodeJS
- cURL
# Sample text to analyze
sample_text = "The Milvus vector database is built for scale!"
# Run analyzer with the defined configuration
result = client.run_analyzer(sample_text, analyzer_params)
print("Analyzer output:", result)
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.vector.request.RunAnalyzerReq;
import io.milvus.v2.service.vector.response.RunAnalyzerResp;
import java.util.ArrayList;
import java.util.List;
ConnectConfig config = ConnectConfig.builder().uri("YOUR_CLUSTER_ENDPOINT").token("YOUR_CLUSTER_TOKEN").build();
MilvusClientV2 client = new MilvusClientV2(config);
List<String> texts = new ArrayList<>();
texts.add("The Milvus vector database is built for scale!");
RunAnalyzerResp resp = client.runAnalyzer(RunAnalyzerReq.builder()
.texts(texts)
.analyzerParams(analyzerParams)
.build());
System.out.println(resp.getResults());
import (
"context"
"encoding/json"
"fmt"
"github.com/milvus-io/milvus/client/v3/milvusclient"
)
ctx := context.Background()
client, err := milvusclient.New(ctx, &milvusclient.ClientConfig{
Address: "YOUR_CLUSTER_ENDPOINT",
APIKey: "YOUR_CLUSTER_TOKEN",
})
if err != nil {
fmt.Println(err.Error())
}
bs, _ := json.Marshal(analyzerParams)
texts := []string{"The Milvus vector database is built for scale!"}
option := milvusclient.NewRunAnalyzerOption(texts...).
WithAnalyzerParamsStr(string(bs))
result, err := client.RunAnalyzer(ctx, option)
if err != nil {
fmt.Println(err.Error())
}
for _, r := range result {
for _, token := range r.Tokens {
fmt.Println("Analyzer output:", token.Text)
}
}
use milvus::v2::prelude::*;
let resp = client.run_analyzer(RunAnalyzerRequest::builder()
.texts(vec!["The Milvus vector database is built for scale!"])
.analyzer_params(analyzer_params)
.build()?).await?;
println!("{:?}", resp.results());
#include "milvus/MilvusClientV2.h"
#include <iostream>
milvus::RunAnalyzerRequest request;
request.WithAnalyzerParams(analyzer_params);
request.AddText("The Milvus vector database is built for scale!");
milvus::RunAnalyzerResponse response;
status = client->RunAnalyzer(request, response);
if (!status.IsOk()) {
std::cout << status.Message() << std::endl;
}
import { MilvusClient } from "@zilliz/milvus2-sdk-node";
const client = new MilvusClient({ address: "YOUR_CLUSTER_ENDPOINT", token: "YOUR_CLUSTER_TOKEN" });
const result = await client.runAnalyzer({
text: "The Milvus vector database is built for scale!",
analyzer_params,
});
console.log(result.results);
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/common/run_analyzer" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--data '{
"text": ["The Milvus vector database is built for scale!"],
"analyzerParams": "{\"type\": \"english\"}"
}'
確認すべき一般的な問題:
-
トークン化の過剰: 技術用語が誤って分割される
-
トークン化の不足: フレーズが適切に分離されない
-
トークンの欠落: 重要な用語がフィルターで除外される
詳細な使用方法については、run_analyzer を参照してください。
ユースケース別のクイックレシピ
このセクションでは、Zilliz Cloud でアナライザーを使用する際の一般的なユースケース向けに、推奨されるトークナイザーとフィルターの構成を示します。コンテンツの種類と検索要件に最も適合する組み合わせを選択してください。
アナライザーをコレクションに適用する前に、run_analyzer を使用してテキスト分析のパフォーマンスをテストおよび検証することをお勧めします。
英語
{
"tokenizer": "standard",
"filter": [
"lowercase",
{
"type": "stemmer",
"language": "english"
},
{
"type": "stop",
"stop_words": [
"_english_"
]
}
]
}
中国語
{
"tokenizer": "jieba",
"filter": ["cnalphanumonly"]
}
アラビア語
{
"tokenizer": "standard",
"filter": [
"lowercase",
{
"type": "stemmer",
"language": "arabic"
}
]
}
ベンガル語
{
"tokenizer": "icu",
"filter": ["lowercase", {
"type": "stop",
"stop_words": []
}]
}
フランス語
{
"tokenizer": "standard",
"filter": [
"lowercase",
{
"type": "stemmer",
"language": "french"
},
{
"type": "stop",
"stop_words": [
"_french_"
]
}
]
}
ドイツ語
{
"tokenizer": "standard",
"filter": [
"lowercase",
{
"type": "stemmer",
"language": "german"
},
{
"type": "stop",
"stop_words": [
"_german_"
]
}
]
}
ヒンディー語
{
"tokenizer": "icu",
"filter": ["lowercase", {
"type": "stop",
"stop_words": []
}]
}
韓国語
{
"tokenizer": {
"type": "lindera",
"dict_kind": "ko-dic",
"filter": [
{
"kind": "korean_stop_tags",
"tags": ["SP", "SSC", "SSO", "SC", "SE", "SF", "JKS", "JKC", "JKG", "JKO", "JKB", "JKV", "JKQ", "JX", "JC", "UNK", "EP", "ETM"]
}
]
}
}
日本語
{
"tokenizer": {
"type": "lindera",
"dict_kind": "ipadic"
},
"filter": [
"removepunct"
]
}
ポルトガル語
{
"tokenizer": "standard",
"filter": [
"lowercase",
{
"type": "stemmer",
"language": "portuguese"
},
{
"type": "stop",
"stop_words": [
"_portuguese_"
]
}
]
}
ロシア語
{
"tokenizer": "standard",
"filter": [
"lowercase",
{
"type": "stemmer",
"language": "russian"
},
{
"type": "stop",
"stop_words": [
"_russian_"
]
}
]
}
スペイン語
{
"tokenizer": "standard",
"filter": [
"lowercase",
{
"type": "stemmer",
"language": "spanish"
},
{
"type": "stop",
"stop_words": [
"_spanish_"
]
}
]
}
スワヒリ語
{
"tokenizer": "standard",
"filter": ["lowercase", {
"type": "stop",
"stop_words": []
}]
}
トルコ語
{
"tokenizer": "standard",
"filter": [
"lowercase",
{
"type": "stemmer",
"language": "turkish"
}
]
}
ウルドゥー語
{
"tokenizer": "icu",
"filter": ["lowercase", {
"type": "stop",
"stop_words": []
}]
}
混在または多言語コンテンツ
コンテンツが複数の言語にまたがる場合や、文字体系が予測不可能な方法で使用される場合は、icu アナライザーから始めてください。この Unicode 対応アナライザーは、混在した文字体系と記号を効果的に処理します。
基本的な多言語構成(ステミングなし):
- Python
- Java
- Go
- Rust
- C++
- NodeJS
- cURL
analyzer_params = {
"tokenizer": "icu",
"filter": ["lowercase", "asciifolding"]
}
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
Map<String, Object> analyzerParams = new HashMap<>();
analyzerParams.put("tokenizer", "icu");
analyzerParams.put("filter", Arrays.asList("lowercase", "asciifolding"));
analyzerParams := map[string]any{
"tokenizer": "icu",
"filter": []any{"lowercase", "asciifolding"},
}
use serde_json::json;
let analyzer_params = serde_json::json!({
"tokenizer": "icu",
"filter": ["lowercase", "asciifolding"]
});
nlohmann::json analyzer_params = {
{"tokenizer", "icu"},
{"filter", {"lowercase", "asciifolding"}}
};
const analyzer_params = {
tokenizer: "icu",
filter: ["lowercase", "asciifolding"],
};
export analyzerParams='{
"tokenizer": "icu",
"filter": ["lowercase", "asciifolding"]
}'
高度な多言語処理:
異なる言語にわたるトークン動作をより細かく制御するには:
Zilliz Cloud でアナライザーを構成してプレビューする
Zilliz Cloud では、コードを書かずに Zilliz Cloud コンソール から直接テキストアナライザーを構成してテストできます。