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

StructArray を使用した範囲検索

このページでは、StructArray のベクトルサブフィールドに対して範囲検索を実行する方法について説明します。範囲検索は、スコアまたは距離が指定された境界内にあるベクトルヒットを返します。StructArray フィールドの場合は、各 Struct 要素を個別に検索する要素レベルのベクトル検索で範囲検索を使用します。

このページでは、StructArray フィールドを作成する の tech_articles コレクションを使用します。このコレクションには、chunks という名前の StructArray フィールドがあります。chunks[emb] ベクトルサブフィールドは、COSINE、IP、L2 などの通常のベクトルメトリックを使用した要素レベル検索用にインデックス化されています。

StructArray における範囲検索の適用方法​

検索モード範囲検索の動作結果の粒度
EmbeddingList 検索サポートされていません。該当しません。
要素レベル検索radius を指定し、必要に応じて range_filter も指定した通常のベクトルクエリを使用します。Struct 要素レベル。
ハイブリッド検索StructArray リクエストが要素レベルのベクトルフィールドを対象とする場合にサポートされます。EmbeddingList レベルのリクエストでは範囲検索はサポートされません。要素レベルのサブ検索の後、ハイブリッド再ランキングが行われます。
Notes

最近傍の Struct 要素のみが必要な場合は、StructArray を使用した基本ベクトル検索 から始めてください。結果が top-K ランキングだけでなくスコアまたは距離の境界を満たす必要がある場合は、範囲検索を使用します。

事前準備​

範囲検索を実行する前に、コレクション、データ、インデックスを準備してください。

要件詳細
StructArray フィールドコレクションには、chunks などの StructArray フィールドが含まれています。
要素レベルのベクトルサブフィールド対象のベクトルサブフィールドは chunks[emb] であり、chunks[emb_list_vector] ではありません。
インデックスのメトリックベクトルサブフィールドは、COSINE、IP、L2 などの通常のベクトルメトリックでインデックス化されています。
クエリデータクエリは通常のベクトルであり、EmbeddingList ではありません。

インデックスの設定については、StructArray フィールドのインデックス化 を参照してください。

radius と range_filter を使用する​

検索境界を定義するには、radius を設定します。内側の境界も必要な場合は、range_filter を設定します。方向は、小さい距離ほど良いか、大きい類似度スコアほど良いかによって異なります。

メトリックタイプスコアが高いほど良いですか?range_filter を使用する場合の範囲条件
L2いいえ。距離が小さいほど良くなります。range_filter <= distance < radius
IP、COSINEはい。スコアが大きいほど良くなります。radius < distance <= range_filter

radius のみを設定した場合、範囲検索はそのメトリックの外側の境界を満たすヒットを返します。埋め込みのスコアまたは距離のスケールに合わせて値を選択してください。

次の例では、chunks[emb] ベクトルがクエリベクトルに十分類似している個々のチャンクを検索します。各結果ヒットは、一致した Struct 要素を表します。

python
from pymilvus import MilvusClient

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

query_vector = [0.19, 0.24, 0.30, 0.37]

results = client.search(
collection_name="tech_articles",
data=[query_vector],
anns_field="chunks[emb]",
search_params={
"params": {
"radius": 0.80,
"range_filter": 0.95,
},
},
limit=10,
output_fields=[
"doc_id",
"title",
"chunks[text]",
"chunks[section]",
"chunks[page]",
"chunks[quality_score]",
],
)

for hits in results:
for hit in hits:
print(
"doc_id:", hit["id"],
"distance:", hit["distance"],
"offset:", hit.get("offset"),
"entity:", hit["entity"],
)

この例では、COSINE は類似度ベースのメトリックであるため、結果の範囲は radius より大きく、range_filter 以下です。offset 値は、返されたときに chunks 配列内で一致した Struct 要素を識別します。

スカラーフィルターを追加する​

要素レベルの範囲検索を StructArray のスカラーフィルタリングと組み合わせることができます。親エンティティのフィールドにはトップレベルの述語を使用し、ベクトル範囲検索に参加する Struct 要素を制限するには element_filter を使用します。

python
from pymilvus import MilvusClient

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

query_vector = [0.19, 0.24, 0.30, 0.37]

filter_expr = (
'category == "search" && '
'element_filter(chunks, '
'$[section] == "index" && '
'$[quality_score] > 0.9)'
)

results = client.search(
collection_name="tech_articles",
data=[query_vector],
anns_field="chunks[emb]",
search_params={
"params": {
"radius": 0.80,
"range_filter": 0.95,
},
},
filter=filter_expr,
limit=10,
output_fields=[
"doc_id",
"title",
"category",
"chunks[text]",
"chunks[section]",
"chunks[quality_score]",
],
)

トップレベルの述語は候補エンティティを選択します。element_filter 述語は、ベクトル範囲検索を一致する Struct 要素に制限します。その他のフィルタリング例については、StructArray を使用したフィルター付き検索 を参照してください。

StructArray の要素レベルベクトルフィールドは、ハイブリッド検索での範囲検索をサポートしています。StructArray の要素レベルベクトルフィールドを対象とする AnnSearchRequest に、radius と、必要に応じて range_filter を追加します。

python
from pymilvus import MilvusClient, AnnSearchRequest, RRFRanker

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

query_vector = [0.19, 0.24, 0.30, 0.37]

title_req = AnnSearchRequest(
data=[query_vector],
anns_field="title_vector",
param={},
limit=10,
)

chunk_req = AnnSearchRequest(
data=[query_vector],
anns_field="chunks[emb]",
param={
"params": {
"radius": 0.80,
"range_filter": 0.95,
},
},
limit=10,
expr='element_filter(chunks, $[section] == "index")',
)

results = client.hybrid_search(
collection_name="tech_articles",
reqs=[title_req, chunk_req],
ranker=RRFRanker(),
limit=5,
output_fields=[
"doc_id",
"title",
"chunks[text]",
"chunks[section]",
"chunks[quality_score]",
],
)

この例では、chunks[emb] サブリクエストのみが範囲検索パラメーターを使用します。StructArray リクエストは引き続き要素レベルのセマンティクスに従います。範囲境界は、ハイブリッド検索が結果を統合して再ランキングする前に、Struct 要素のヒットに適用されます。

範囲検索の結果を解釈する​

結果項目意味
id一致した Struct 要素を含むエンティティの主キー。
distance またはスコアクエリベクトルと、一致した Struct 要素ベクトルの間のスコアまたは距離。
offset返されたときの、StructArray フィールド内での一致した Struct 要素の 0 から始まる位置。
主キーの重複発生する可能性があります。同じエンティティ内の複数の Struct 要素が指定された範囲に含まれることがあります。
limit一意の親エンティティではなく、要素のヒットに適用されます。

制限事項​

  • StructArray のベクトルサブフィールドに対する範囲検索では、EmbeddingList クエリまたは MAX_SIM* メトリックを使用しないでください。EmbeddingList レベルの検索では、範囲検索はサポートされていません。

  • 範囲検索とグループ化検索を組み合わせないでください。親エンティティごとに 1 件の結果が必要な場合は、範囲パラメーターを指定せずに要素レベルの検索を実行し、サポートされている場合はグループ化を使用してください。

  • ハイブリッド範囲検索は、StructArray の要素レベルベクトルフィールドでサポートされています。EmbeddingList レベルの StructArray リクエストではサポートされていません。

よくある間違い​

  • chunks[emb_list_vector] に対して範囲検索を実行することです。これは EmbeddingList 検索を目的としています。

  • 要素レベルの範囲検索で、COSINE などの通常のメトリックの代わりに MAX_SIM_COSINE を使用することです。

  • 通常のベクトルクエリの代わりに EmbeddingList クエリを使用することです。

  • 範囲検索の結果が親エンティティごとに一意であると期待することです。範囲検索は、一致する Struct 要素のヒットを返します。

  • 必須のサブフィールドパス構文 chunks[emb] の代わりに chunks.emb を使用することです。

次のステップ​

  1. StructArray の 2 つの基本的なベクトル検索モードについては、StructArray を使用した基本ベクトル検索 を参照してください。

  2. 範囲検索にスカラーフィルターを追加するには、StructArray を使用したフィルター付き検索 を参照してください。

  3. サポートされている場合に親エンティティごとに最大 1 件の結果を返すには、StructArray を使用したグループ化検索 を参照してください。

  4. バージョン固有の検索制限を確認するには、StructArray の制限 を参照してください。