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

基本的なベクトル検索

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

📘Notes

コレクションの作成後に新しいフィールドを追加した場合、これらのフィールドを含む検索では、値を明示的に設定していないエンティティに対して、定義されたデフォルト値または NULL が返されます。詳細は、コレクションスキーマの変更 を参照してください。

概要​

ANN 検索と k-Nearest Neighbors(kNN)検索は、ベクトル類似検索で一般に使用される手法です。kNN 検索では、検索リクエストに含まれるクエリベクトルとベクトル空間内のすべてのベクトルを比較してから、最も類似したベクトルを特定する必要があるため、時間とリソースがかかります。

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

ANN 検索は構築済みのインデックスに依存し、検索スループット、メモリ使用量、検索の正確性は、選択するインデックスタイプによって異なる場合があります。検索パフォーマンスと正確性のバランスを取る必要があります。

学習曲線を緩和するため、Zilliz Cloud は AUTOINDEX を提供しています。AUTOINDEX を使用すると、Zilliz Cloud はインデックスの構築中にコレクション内のデータ分布を分析し、分析結果に基づいて最適化されたインデックスパラメーターを設定することで、検索パフォーマンスと正確性のバランスを取ります。

ANN 検索では、単一ベクトル検索とは、1 つのクエリベクトルのみを使用する検索を指します。事前に構築されたインデックスと検索リクエストに含まれるメトリックタイプに基づいて、Zilliz Cloud はクエリベクトルに最も類似した上位 K 件のベクトルを検索します。

このセクションでは、単一ベクトル検索を実行する方法について説明します。検索リクエストには 1 つのクエリベクトルが含まれ、Zilliz Cloud が内積(IP)を使用してクエリベクトルとコレクション内のベクトル間の類似度を計算し、最も類似した 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,
search_params={"metric_type": "IP"}
)

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": {}
# }
# ]
# ]

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

次の表に、適用可能なメトリックタイプと対応する距離の範囲を示します。

メトリックタイプ

特性

距離範囲

L2

値が小さいほど類似度が高くなります。

[0, ∞)

IP

値が大きいほど類似度が高くなります。

[-1, 1]

COSINE

値が大きいほど類似度が高くなります。

[-1, 1]

JACCARD

値が小さいほど類似度が高くなります。

[0, 1]

HAMMING

A smaller value indicates a higher similarity.

[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": {}
# }
# ]
# ]

クエリベクトルを設定する代わりに、クエリベクトルがターゲットコレクションにすでに存在する場合は、主キーを使用できます。

python
res = client.search(
collection_name="quick_setup",
anns_field="vector",
ids=[551, 296, 43],
limit=3,
search_params={"metric_type": "IP"}
)

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

パーティションでの ANN 検索​

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

次のコードスニペットは、コレクション内に PartitionA という名前のパーティションがあることを前提としています。

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 件のベクトル埋め込みを含むエンティティのプライマリフィールドの値と類似度の距離(distance/scores)が含まれます。検索リクエストで出力フィールドとして対象フィールド(ベクトルフィールドとスカラーフィールドの両方)の名前を指定すると、検索結果にこれらのエンティティの他のフィールドの値を含めることができます。

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={"metric_type": "IP"},
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"
# }
# }
# ]
# ]

スカラーフィールドで検索結果を並べ替える​

Public Preview

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

order_by_fields の各項目は、スカラーフィールドと並べ替え方向を指定します。昇順には "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"}
],
)

複数のスカラーフィールドで並べ替えることもできます。Zilliz Cloud は指定した順序でフィールドを適用します。次の例では、Zilliz Cloud は結果を price の昇順で並べ替えます。price が同じエンティティについては、Zilliz Cloud は次に 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"},
],
)

指定したすべての並べ替えフィールドで同じ値を持つエンティティについては、Zilliz Cloud は元の類似度スコア順を維持します。

limit と offset の使用​

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

ページ分割されたクエリを実行する場合は、ループを使用して複数の検索リクエストを送信し、各クエリリクエストに Limit パラメーターと Offset パラメーターを含めます。具体的には、Limit パラメーターに現在のクエリ結果に含めるエンティティの数を設定し、Offset にすでに返されたエンティティの合計数を設定します。

次の表は、一度に 100 件のエンティティを返す場合に、ページ分割されたクエリの Limit パラメーターと Offset パラメーターを設定する方法を示しています。

クエリ

クエリごとに返すエンティティ数

これまでに返されたエンティティの合計数

1 回目のクエリ

100

0

2 回目のクエリ

100

100

3 回目のクエリ

100

200

n 回目のクエリ

100

100 x (n-1)

1 回の ANN 検索における limit と offset の合計は 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={
"metric_type": "IP",
"offset": 10 # The records to skip
}
)

コレクションに TIMESTAMPTZ フィールドがある場合、検索呼び出しで timezone パラメーターを設定すると、1 回の操作に対してデータベースまたはコレクションのデフォルトタイムゾーンを一時的に上書きできます。これは、操作中に TIMESTAMPTZ 値が表示および比較される方法を制御します。

timezone の値は、有効な IANA タイムゾーン識別子(たとえば、Asia/Shanghai, America/Chicago, または UTC)である必要があります。TIMESTAMPTZ フィールドの使用方法の詳細は、TIMESTAMPTZ フィールド を参照してください。

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

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

AUTOINDEX は ANN 検索の学習曲線を大幅に緩和します。ただし、上位 K 件が増えるにつれて、検索結果が常に正確であるとは限りません。Zilliz Cloud は、検索範囲を狭め、検索結果の関連性を高め、検索結果を多様化することで、次の検索機能強化を実現しています。

  • フィルタ検索

    検索リクエストにフィルタリング条件を含めると、Zilliz Cloud は ANN 検索を実行する前にメタデータフィルタリングを実行し、検索範囲をコレクション全体から指定したフィルタリング条件に一致するエンティティのみに絞り込むことができます。

    メタデータフィルタリングとフィルタ条件の詳細は、フィルタ検索、フィルタリングの概要、および関連トピックを参照してください。

  • 範囲検索

    返されるエンティティの距離またはスコアを特定の範囲内に制限することで、検索結果の関連性を高めることができます。Zilliz Cloud では、範囲検索は、クエリベクトルに最も類似したベクトル埋め込みを中心として 2 つの同心円を描くことを含みます。検索リクエストで両方の円の半径を指定すると、Zilliz Cloud は外側の円内にあり、内側の円内にないすべてのベクトル埋め込みを返します。

    範囲検索の詳細は、範囲検索 を参照してください。

  • グループ化検索

    返されるエンティティが特定のフィールドで同じ値を持つ場合、検索結果はベクトル空間内のすべてのベクトル埋め込みの分布を表していない可能性があります。検索結果を多様化するには、グループ化検索の使用を検討してください。

    グループ化検索の詳細は、グループ化検索 を参照してください。

  • ハイブリッド検索

    コレクションには、異なる埋め込みモデルを使用して生成されたベクトル埋め込みを保存するために、複数のベクトルフィールドを含めることができます。これにより、ハイブリッド検索を使用してこれらのベクトルフィールドからの検索結果を再ランク付けし、再現率を向上させることができます。

    ハイブリッド検索の詳細は、ハイブリッド検索 を参照してください。

  • 検索イテレーター

    1 回の ANN 検索では最大 16,384 件のエンティティが返されます。1 回の検索でより多くのエンティティを返す必要がある場合は、検索イテレーターの使用を検討してください。

    検索イテレーターの詳細は、検索イテレーター を参照してください。

  • 全文検索

    全文検索は、テキストデータセット内の特定の用語またはフレーズを含むドキュメントを取得し、関連性に基づいて結果をランク付けする機能です。この機能は、正確な用語を見落とす可能性があるセマンティック検索の制限を克服し、最も正確で文脈に関連した結果を得られるようにします。さらに、生のテキスト入力を受け付け、手動でベクトル埋め込みを生成することなくテキストデータを自動的にスパース埋め込みに変換することで、ベクトル検索を簡素化します。

    全文検索の詳細は、全文検索 を参照してください。

  • テキスト一致

    Zilliz Cloud のキーワード一致により、特定の用語に基づく正確なドキュメント取得が可能になります。この機能は主に、特定の条件を満たすためのフィルタ検索に使用され、スカラーフィルタリングを組み込んでクエリ結果を絞り込み、スカラー条件を満たすベクトル内での類似検索を可能にします。

    キーワード一致の詳細は、キーワード一致 を参照してください。

  • パーティションキーの使用

    メタデータフィルタリングで複数のスカラーフィールドを扱い、かなり複雑なフィルタ条件を使用すると、検索効率に影響する可能性があります。スカラーフィールドをパーティションキーとして設定し、検索リクエストでパーティションキーを含むフィルタ条件を使用すると、検索範囲を指定したパーティションキー値に対応するパーティション内に制限するのに役立ちます。

    パーティションキーの詳細は、パーティションキーの使用 を参照してください。

  • mmap の使用

    mmap 設定の詳細は、mmap の使用 を参照してください。

  • クラスタリング Compaction

    クラスタリング Compaction の詳細は、クラスタリング Compaction を参照してください。

  • 再ランキングの使用

    検索結果の関連性を高めるためにランカーを使用する方法の詳細は、Decay Ranker Overview および Model Ranker Overview を参照してください。

level の使用​

ANN 検索を最適化するため、Zilliz Cloud は、検索の最適化を簡素化しながら検索精度を制御する level という名前のパラメーターを提供しています。

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

📘Notes

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

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
}
}
)

再現率の取得​

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

📘Notes

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

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
}
}
)