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

基本的なベクトル検索

ベクトル埋め込みのソート順を記録したインデックスファイルに基づき、Approximate Nearest Neighbor (ANN) 検索は、受信した検索リクエストに含まれるクエリベクトルに基づいてベクトル埋め込みのサブセットを特定し、そのサブグループ内のベクトルとクエリベクトルを比較して、最も類似した結果を返します。ANN 検索により、Zilliz Cloud は効率的な検索体験を提供します。このページでは、基本的な ANN 検索の実行方法を学べます。

📘注意

collection の作成後に新しいフィールドを追加した場合、それらのフィールドを含む検索では、値が明示的に設定されていない entity に対して、定義されたデフォルト値または NULL が返されます。詳細については、Alter Collection Schema を参照してください。

概要

ANN 検索と k-Nearest Neighbors(kNN)検索は、ベクトル類似性検索で一般的に使用される方法です。kNN 検索では、最も類似したベクトルを見つける前に、ベクトル空間内のすべてのベクトルを検索リクエストに含まれるクエリベクトルと比較する必要があるため、時間とリソースを多く消費します。

kNN 検索とは異なり、ANN 検索アルゴリズムでは、ベクトル埋め込みのソート順を記録した index ファイルが必要です。検索リクエストが届くと、この index ファイルを参照して、クエリベクトルに最も類似している可能性が高いベクトル埋め込みを含むサブグループをすばやく特定できます。次に、指定された metric type を使用してクエリベクトルとサブグループ内のベクトルとの類似度を測定し、クエリベクトルとの類似度に基づいてグループメンバーを並べ替え、top-K のグループメンバーを特定できます。

ANN 検索は事前に構築された index に依存しており、選択する index type によって検索スループット、メモリ使用量、検索の正確性が異なる場合があります。検索パフォーマンスと正確性のバランスを取る必要があります。

学習コストを下げるために、Zilliz Cloud は AUTOINDEX を提供しています。AUTOINDEX を使用すると、Zilliz Cloud は index の構築中に collection 内のデータ分布を分析し、その分析に基づいて最適化された index パラメータを設定し、検索パフォーマンスと正確性のバランスを取ることができます。

AUTOINDEX と適用可能な metric type の詳細については、AUTOINDEX Explained および Metric Types を参照してください。このセクションでは、次のトピックに関する詳細情報を確認できます。

ANN 検索において、単一ベクトル検索とは 1 つのクエリベクトルのみを含む検索を指します。事前に構築された index と、検索リクエストに含まれる metric type に基づいて、Zilliz Cloud はクエリベクトルに最も類似した top-K ベクトルを見つけます。

このセクションでは、単一ベクトル検索の実行方法を学びます。検索リクエストには 1 つのクエリベクトルが含まれ、Zilliz Cloud に対して Inner Product (IP) を使用してクエリベクトルと collection 内のベクトルとの類似度を計算し、最も類似した 3 件を返すよう要求します。

python
from pymilvus import MilvusClient

client = MilvusClient(
uri="YOUR_CLUSTER_ENDPOINT",
token="YOUR_CLUSTER_TOKEN"
)

# 4. Single vector search
query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]
res = client.search(
collection_name="quick_setup",
anns_field="vector",
data=[query_vector],
limit=3
)

for hits in res:
for hit in hits:
print(hit)

# [
# [
# {
# "id": 551,
# "distance": 0.08821295201778412,
# "entity": {}
# },
# {
# "id": 296,
# "distance": 0.0800950899720192,
# "entity": {}
# },
# {
# "id": 43,
# "distance": 0.07794742286205292,
# "entity": {}
# }
# ]
# ]

Milvus は、検索結果をクエリベクトルとの類似度スコアの降順でランク付けします。類似度スコアはクエリベクトルへの距離とも呼ばれ、その値の範囲は使用する metric type によって異なります。

次の表は、適用可能な metric type と対応する距離の範囲を示しています。

Metric TypeCharacteristicsDistance Range
L2値が小さいほど類似度が高いことを示します。[0, ∞)
IP値が大きいほど類似度が高いことを示します。[-1, 1]
COSINE値が大きいほど類似度が高いことを示します。[-1, 1]
JACCARD値が小さいほど類似度が高いことを示します。[0, 1]
HAMMING値が小さいほど類似度が高いことを示します。[0, dim(vector)]

同様に、複数のクエリベクトルを検索リクエストに含めることもできます。Zilliz Cloud はクエリベクトルに対して並列に ANN 検索を実行し、2 組の結果を返します。

python
# 7. Search with multiple vectors
# 7.1. Prepare query vectors
query_vectors = [
[0.041732933, 0.013779674, -0.027564144, -0.013061441, 0.009748648],
[0.0039737443, 0.003020432, -0.0006188639, 0.03913546, -0.00089768134]
]

# 7.2. Start search
res = client.search(
collection_name="quick_setup",
data=query_vectors,
limit=3,
)

for hits in res:
print("TopK results:")
for hit in hits:
print(hit)

# Output
#
# [
# [
# {
# "id": 551,
# "distance": 0.08821295201778412,
# "entity": {}
# },
# {
# "id": 296,
# "distance": 0.0800950899720192,
# "entity": {}
# },
# {
# "id": 43,
# "distance": 0.07794742286205292,
# "entity": {}
# }
# ],
# [
# {
# "id": 730,
# "distance": 0.04431751370429993,
# "entity": {}
# },
# {
# "id": 333,
# "distance": 0.04231833666563034,
# "entity": {}
# },
# {
# "id": 232,
# "distance": 0.04221535101532936,
# "entity": {}
# }
# ]
# ]

クエリベクトルを設定する代わりに、クエリベクトルが対象の collection にすでに存在している場合は、主キーを使用できます。

python
res = client.search(
collection_name="quick_setup",
anns_field="vector",
ids=[551, 296, 43],
limit=3
)

for hits in res:
for hit in hits:
print(hit)

パーティション内の ANN 検索

collection に複数の partition を作成している場合、検索範囲を特定の数の partition に絞り込めます。その場合、検索リクエストに対象の partition 名を含めることで、指定した partition 内に検索範囲を制限できます。検索に関与する partition の数を減らすことで、検索パフォーマンスが向上します。

以下のコードスニペットでは、collection に PartitionA という名前の partition があることを前提としています。

python
# 4. Single vector search
query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]
res = client.search(
collection_name="quick_setup",
partition_names=["partitionA"],
data=[query_vector],
limit=3,
)

for hits in res:
print("TopK results:")
for hit in hits:
print(hit)

# [
# [
# {
# "id": 551,
# "distance": 0.08821295201778412,
# "entity": {}
# },
# {
# "id": 296,
# "distance": 0.0800950899720192,
# "entity": {}
# },
# {
# "id": 43,
# "distance": 0.07794742286205292,
# "entity": {}
# }
# ]
# ]

出力フィールドの使用

検索結果では、Zilliz Cloud はデフォルトで、上位 K 件の vector embedding を含む entity の主フィールド値と類似度 distance/score を返します。これらの entity にある他のフィールドの値も検索結果に含めたい場合は、検索リクエストの output fields として、vector フィールドと scalar フィールドの両方を含む対象フィールド名を指定できます。

python
# 4. Single vector search
query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592],

res = client.search(
collection_name="quick_setup",
data=[query_vector],
limit=3, # The number of results to return
output_fields=["color"]
)

print(res)

# [
# [
# {
# "id": 551,
# "distance": 0.08821295201778412,
# "entity": {
# "color": "orange_6781"
# }
# },
# {
# "id": 296,
# "distance": 0.0800950899720192,
# "entity": {
# "color": "red_4794"
# }
# },
# {
# "id": 43,
# "distance": 0.07794742286205292,
# "entity": {
# "color": "grey_8510"
# }
# }
# ]
# ]

スカラー フィールドによる検索結果の並べ替え | ONDEMAND

デフォルトでは、Zilliz Cloud は検索結果をクエリベクトルに対する類似度スコアで並べます。返される entity を scalar フィールドの順序に従わせたい場合は、検索リクエストに order_by_fields を追加します。

order_by_fields の各項目では、scalar フィールドと並べ替え方向を指定します。昇順には "asc"、降順には "desc" を使用します。order を省略した場合、Zilliz Cloud はそのフィールドを昇順で並べ替えます。

以下の例では、検索結果を price の低い順に並べ替えます。レスポンス内でフィールド値を確認したい場合は、並べ替え対象フィールドを output_fields に含めてください。

python
res = client.search(
collection_name="product_catalog",
data=query_vectors,
anns_field="embedding",
limit=20,
output_fields=["id", "price", "rating", "category"],
order_by_fields=[
{"field": "price", "order": "asc"}
],
)

複数の scalar フィールドで並べ替えることもできます。Zilliz Cloud は、指定した順序でフィールドを適用します。以下の例では、まず price を昇順で並べ替えます。price が同じ entity については、次に rating を降順で並べ替えます。

python
res = client.search(
collection_name="product_catalog",
data=query_vectors,
anns_field="embedding",
limit=20,
output_fields=["id", "price", "rating", "category"],
order_by_fields=[
{"field": "price", "order": "asc"},
{"field": "rating", "order": "desc"},
],
)

指定したすべての order-by フィールドの値が同じ entity については、Zilliz Cloud は元の類似度スコア順を維持します。

Limit と Offset を使用する

検索リクエストに含まれるパラメータ limit が、検索結果に含める entity の数を決定していることに気付くかもしれません。このパラメータは、1 回の検索で返す entity の最大数を指定するもので、通常は top-K と呼ばれます。

ページネーション付きクエリを実行したい場合は、ループを使って複数の Search リクエストを送信し、各クエリリクエストに LimitOffset パラメータを含めることができます。具体的には、Limit パラメータを現在のクエリ結果に含めたい Entities の数に設定し、Offset を、すでに返された Entities の総数に設定します。

以下の表は、1 回あたり 100 Entities を返す場合に、ページネーション付きクエリで LimitOffset パラメータをどのように設定するかを示しています。

クエリクエリごとに返す Entitiesすでに返された Entities の総数
1 回目 のクエリ1000
2 回目 のクエリ100100
3 回目 のクエリ100200
n 回目 のクエリ100100 x (n-1)

なお、1 回の ANN 検索における limitoffset の合計は 16,384 未満である必要があります。

python
# 4. Single vector search
query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592],

res = client.search(
collection_name="quick_setup",
data=[query_vector],
limit=3, # The number of results to return
search_params={
"offset": 10 # The records to skip
}
)

Level を使用する

ANN 検索を最適化するために、Zilliz Cloud では level というパラメータを提供しており、簡易的な検索最適化によって検索精度を制御できます。

このパラメータの範囲は 1 から 10 で、デフォルトは 1 です。値を大きくすると検索の再現率は向上しますが、その代わりに検索パフォーマンスは低下します。一般的なケースでは、デフォルト値で最大 90% の再現率が得られます。必要に応じて値を上げてください。

📘注意

level パラメータは現在も Public Preview です。5 より大きい値に設定できない場合は、使用中の cluster がこの機能を完全にはサポートしていない可能性があります。回避策としては、1 から 5 の範囲の値を設定するか、Zilliz Cloud support にお問い合わせください。

python
# 4. Single vector search
query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592],

res = client.search(
collection_name="quick_setup",
data=[query_vector],
limit=3, # The number of results to return
search_params={
"params": {
"level": 10 # The precision control
}
}
)

Recall Rate を取得する

level パラメータを調整するときに enable_recall_calculationtrue に設定すると、異なる level 値での検索精度を評価できます。

📘注意

enable_recall_calculation パラメータは現在も Public Preview であり、互換性の問題により使用できない場合があります。サポートが必要な場合は、Zilliz Cloud support までお問い合わせください。

python
# 4. Single vector search
query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592],

res = client.search(
collection_name="quick_setup",
data=[query_vector],
limit=3, # The number of results to return
search_params={
"params": {
"level": 10 # The precision control,
"enable_recall_calculation": True # Ask to return recall rate
}
}
)

collection に TIMESTAMPTZ フィールドがある場合、検索呼び出しで timezone パラメータを設定することで、単一の操作に対して database または collection のデフォルトタイムゾーンを一時的に上書きできます。これにより、その操作中に TIMESTAMPTZ の値がどのように表示および比較されるかを制御できます。

timezone の値は、有効な IANA time zone identifier である必要があります(例: Asia/ShanghaiAmerica/ChicagoUTC)。TIMESTAMPTZ フィールドの使用方法の詳細については、TIMESTAMPTZ Field を参照してください。

以下の例は、検索操作に対して一時的にタイムゾーンを設定する方法を示しています。

python
res = client.search(
collection_name="quick_setup",
anns_field="vector",
data=[query_vector],
limit=3,
timezone="America/Havana",
)

AUTOINDEX は ANN Search の学習ハードルを大幅に下げます。しかし、top-K が増加すると、検索結果が常に正しいとは限りません。検索範囲を狭め、検索結果の関連性を高め、検索結果を多様化することで、Zilliz Cloud は以下の検索強化機能を提供します。

  • Filtered Search

    検索リクエストにフィルタリング条件を含めることで、Zilliz Cloud は ANN Search を実行する前に metadata filtering を実施し、検索範囲を collection 全体から、指定されたフィルタリング条件に一致する entities のみに絞り込めます。

    metadata filtering とフィルタリング条件の詳細については、Filtered Search および Filtering Explained を参照してください。

  • Range Search

    返される entities の距離またはスコアを特定の範囲内に制限することで、検索結果の関連性を向上させることができます。Zilliz Cloud では、range search は、クエリ vector に最も類似した vector embedding を中心として 2 つの同心円を描く形で行われます。検索リクエストでは両方の円の半径を指定し、Zilliz Cloud は外側の円の内側かつ内側の円の外側にあるすべての vector embeddings を返します。

    range search の詳細については、Range Search を参照してください。

  • Grouping Search

    返された entities が特定のフィールドで同じ値を持つ場合、検索結果は vector space 内のすべての vector embeddings の分布を表していない可能性があります。検索結果を多様化するには、grouping search の使用を検討してください。

    grouping search の詳細については、Grouping Search を参照してください。

  • Hybrid Search

    collection には、異なる embedding model を使用して生成された vector embeddings を保存するために、複数の vector fields を含めることができます。これにより、hybrid search を使用してこれらの vector fields からの検索結果を rerank し、recall rate を向上させることができます。

    hybrid search の詳細については、Hybrid Search を参照してください。

    collection で許可される vector fields の数の制限の詳細については、Zilliz Cloud Limits を参照してください。

  • Search Iterator

    1 回の ANN Search で返される entities の最大数は 16,384 です。1 回の検索でさらに多くの entities を返す必要がある場合は、search iterators の使用を検討してください。

    search iterators の詳細については、Search Iterator を参照してください。

  • Full-Text Search

    full text search は、テキストデータセット内で特定の用語やフレーズを含むドキュメントを取得し、その後関連性に基づいて結果をランク付けする機能です。この機能は semantic search の制限を補い、正確な用語が見落とされる可能性を回避して、より正確で文脈に即した結果を得られるようにします。さらに、生のテキスト入力を受け付け、テキストデータを自動的に sparse embeddings に変換することで、手動で vector embeddings を生成する必要をなくし、vector search を簡素化します。

    full-text search の詳細については、Full Text Search を参照してください。

  • Text Match

    Zilliz Cloud の keyword match は、特定の用語に基づいて正確なドキュメント取得を可能にします。この機能は主に filtered search で特定の条件を満たすために使用され、scalar filtering を組み合わせてクエリ結果を絞り込み、scalar 条件を満たす vectors に対する類似検索を可能にします。

    keyword match の詳細については、Keyword Match を参照してください。

  • Use Partition Key

    metadata filtering に複数の scalar fields を含め、かなり複雑なフィルタリング条件を使用すると、検索効率に影響する可能性があります。scalar field を partition key として設定し、検索リクエストで partition key を含むフィルタリング条件を使用すると、指定した partition key の値に対応する partitions 内に検索範囲を制限するのに役立ちます。

    partition key の詳細については、Use Partition Key を参照してください。

  • Use mmap

    mmap-settings の詳細については、Use mmap を参照してください。

Ctrl I