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

Search Aggregation

買い物客が「毎日のトレーニング用の黒いランニングシューズ」を検索すると、近似最近傍(ANN)検索はベクトル類似度に基づいて商品をランク付けし、フラットな Top-K リストを返します。結果は関連性が高いこともありますが、重複が生じます。以下の例では、最初の 6 件のうち 4 件がブランド A の商品で、ブランド B とブランド C はそれぞれ 1 件ずつしか出現しません。

フラットなリストでは、バケット単位のサマリーを直接提供できません。アプリケーションによっては、保持された候補数や平均価格でブランドを比較したり、各ブランドから少数の代表的な商品を確認したり、結果を複数のバケット階層に整理したりする必要があります。

Search Aggregation は、保持された ANN 候補を、選択したスカラーフィールドに基づいてバケットに整理します。この例では、各ブランドが個別のバケットになります。Zilliz Cloud は、各バケットの統計を計算し、バケットを並べ替え、代表的な商品を添付できます。アプリケーションは、このバケット優先のレスポンスを result.agg_buckets を通じて受け取ります。

CPHkwKQTRhuEQKbsxdacRZuCnVe

Search Aggregation は、コレクション全体を対象とした厳密な集計を実行しません。バケットの存在、件数、メトリクス、順序、および代表ヒットは、ANN ステージとグループ化ステージで保持された候補に依存します。

仕組み

Edbbw7oulhszR2baU7BcsjiMntf

  1. 候補の取得。 Zilliz Cloud は ANN 検索を実行し、クエリベクトルに最も近いエンティティを検索します。次に、グループ化ステージが完全な複合キーごとに一定数の候補を保持します。このキーごとの候補バジェットは、集計ツリー内のどこかで最大の TopHits.size であるか、どのレベルでも top_hits を設定しない場合は 1 です。

  2. バケットの構築。 SearchAggregation.fields パラメーターがバケットキーを定義します。フィールド値の一意の組み合わせごとに個別のキーが作成されます。図では、fields=["brand"] によって (Brand A)(Brand B)(Brand C) のバケットキーが作成されます。同じキーを持つ保持候補は同じバケットに属し、その count に寄与します。SearchAggregation.size は、Zilliz Cloud が返すバケット数を制限します。

  3. 結果の計算と返却。 返される各バケットには、そのキーと保持された候補数が含まれます。Zilliz Cloud は、設定されたメトリクスの計算、バケットの並べ替え、代表エンティティの返却、子バケットの構築も実行できます。result.agg_buckets 内の各 AggregationBucket は、keycountmetricshitssub_groups を公開します。Search Aggregation が有効な場合、通常の検索ヒットリストは空になります。

図では、TopHits.size=4 がキーごとの候補バジェットを 4 に設定するため、保持された 4 件のブランド A 候補から count: 4 が生成されます。完成したブランド A カードには、図を簡潔に保つため、返された 4 件の代表ヒットのうち 2 件のみが表示されています。

sub_aggregation を使用すると、Zilliz Cloud は各親バケット内でステップ 2 と 3 を繰り返します。ANN の再現率やキーごとの候補バジェットが変化すると、バケットの件数、メトリクス、順序、ヒット、およびネストされた結果が変化する可能性があります。

制限事項

Search Aggregation を使用する前に、以下の制限事項に注意してください。

  • ネストされた集計: 1 つのリクエストには、1 つのルート SearchAggregation と最大 3 レベルのネストされた sub_aggregation を含めることができ、合計で最大 4 レベルになります。すべてのレベルを通じて、バケットキーの作成に使用できるフィールドは最大 10 個です。

  • バケットキーの作成に使用するフィールド。 SearchAggregation.fields パラメーターは、Boolean、整数、VARCHARTIMESTAMPTZ フィールドをサポートします。FLOATDOUBLEARRAYJSONGEOMETRYTEXT、ベクトル、動的フィールドはサポートしません。

  • メトリクスフィールド。 count 操作は "*" または任意の非 JSON かつ非動的フィールドを受け入れ、フィールドを指定した場合は NULL 値をスキップします。sumavg は整数および浮動小数点フィールドを受け入れます。minmax は、さらに文字列および TIMESTAMPTZ フィールドを受け入れます。

  • Top Hits のソートフィールド。 TopHits.sort パラメーターは、比較可能な Boolean、整数、浮動小数点、文字列、TIMESTAMPTZ フィールドに加えて _score を受け入れます。ARRAYJSONGEOMETRY、ベクトル、動的フィールドはサポートしません。

  • 候補バジェット: 集計ツリー内のどこかで最大の TopHits.size は、完全な複合キーごとに保持される候補数でもあります。どのレベルでも top_hits を設定しない場合、Zilliz Cloud はキーごとに 1 件の候補を保持します。バケットの count とメトリクスはこれらの保持された候補から計算されるため、TopHits.size を変更するとそれらも変わる可能性があります。

  • null 許容のバケットフィールド: NULL 値は独自のバケットキーを形成します。null バケットを除外するには、検索リクエストに brand is not null などのフィルターを追加します。

  • 重複するフィールド: 同じフィールドを複数の SearchAggregation.fields リストに含めることはできません。例えば、ルート集計で fields=["category"] を使用する場合、ネストされた sub_aggregation でも fields=["category"] を使用することはできません。

  • サポートされない組み合わせ: Search Aggregation は、ゼロ以外の offset、Search Iterators、Hybrid Search、Highlighter、Grouping Search と組み合わせることはできません。トップレベルの offset 値が 0 の場合は、パラメーターを省略した場合と同じです。REST v2 プロトコルレベルでは、searchAggregationids を同時に指定することはできません。

  • 返されるエントリ数。 計算される結果エントリの最大数を 10,000 以下に保ってください。サーバーはこの最大値を number of query vectors × product of the effective search_size at every aggregation level × largest TopHits.size at any level として計算します。

    どのレベルでも TopHits を設定しない場合は、最後の係数に 1 を使用します。例えば、1 つのクエリベクトル、10 個のルートバケット、ルートバケットあたり 5 個の子バケット、子バケットあたり 2 件のヒットの場合、計算される最大値は 1 × 10 × 5 × 2 = 100 です。

Search Aggregation の使用

達成したい内容に基づいて例を選択してください。

移動先説明主な設定
バケットの比較と並べ替えバケットごとの統計を計算してバケットを比較し、返されたバケットをメトリクス、件数、またはキーで並べ替えます。fieldssizemetricsorder
各バケットから代表的な結果を表示各バケットから限られた数のエンティティを返し、それらのエンティティをスカラーフィールドまたはベクトルスコアで個別に並べ替えます。top_hitsTopHits.sizeTopHits.sort
複数レベルでの結果のグループ化結果を親バケットと子バケットのレベルに整理し、複数のディメンションを順番に分析します。sub_aggregation

以下の例では、brand、category、color、price、rating の各フィールドを持つ商品コレクションを使用します。すべてのブランド名、商品名、価格、評価、検索結果は合成されたサンプルデータです。次のセクションを展開して、コレクションを作成し、共通の検索変数を定義してください。

サンプルコレクションのセットアップ
python
from pymilvus import DataType, MilvusClient, SearchAggregation, TopHits

client = MilvusClient(
uri="YOUR_CLUSTER_OR_PROJECT_ENDPOINT",
token="YOUR_AUTHORIZED_TOKEN",
)

collection_name = "product_search_aggregation"

if client.has_collection(collection_name):
client.drop_collection(collection_name)

schema = client.create_schema(auto_id=False, enable_dynamic_field=False)
schema.add_field("id", DataType.INT64, is_primary=True)
schema.add_field("embedding", DataType.FLOAT_VECTOR, dim=5)
schema.add_field("name", DataType.VARCHAR, max_length=200)
schema.add_field("brand", DataType.VARCHAR, max_length=100)
schema.add_field("category", DataType.VARCHAR, max_length=100)
schema.add_field("color", DataType.VARCHAR, max_length=50)
schema.add_field("price", DataType.DOUBLE)
schema.add_field("rating", DataType.DOUBLE)
schema.add_field("in_stock", DataType.BOOL)

index_params = client.prepare_index_params()
index_params.add_index(
field_name="embedding",
index_type="AUTOINDEX",
metric_type="COSINE",
)

client.create_collection(
collection_name=collection_name,
schema=schema,
index_params=index_params,
# Make preceding writes visible to searches from this client.
consistency_level="Session",
)

client.insert(
collection_name=collection_name,
data=[
{
"id": 1,
"embedding": [0.12, 0.42, 0.18, 0.66, 0.31],
"name": "Runner A1",
"brand": "Brand A",
"category": "running_shoes",
"color": "black",
"price": 129.99,
"rating": 4.7,
"in_stock": True,
},
{
"id": 2,
"embedding": [0.10, 0.39, 0.20, 0.61, 0.29],
"name": "Trail A2",
"brand": "Brand A",
"category": "running_shoes",
"color": "blue",
"price": 139.99,
"rating": 4.6,
"in_stock": True,
},
{
"id": 3,
"embedding": [0.14, 0.44, 0.19, 0.68, 0.33],
"name": "Runner B1",
"brand": "Brand B",
"category": "running_shoes",
"color": "white",
"price": 159.99,
"rating": 4.8,
"in_stock": True,
},
{
"id": 4,
"embedding": [0.16, 0.41, 0.22, 0.62, 0.30],
"name": "Runner C1",
"brand": "Brand C",
"category": "running_shoes",
"color": "red",
"price": 119.99,
"rating": 4.4,
"in_stock": False,
},
{
"id": 5,
"embedding": [0.48, 0.20, 0.59, 0.15, 0.71],
"name": "Jacket A1",
"brand": "Brand A",
"category": "jackets",
"color": "black",
"price": 99.99,
"rating": 4.5,
"in_stock": True,
},
{
"id": 6,
"embedding": [0.45, 0.18, 0.55, 0.17, 0.69],
"name": "Jacket B1",
"brand": "Brand B",
"category": "jackets",
"color": "blue",
"price": 89.99,
"rating": 4.3,
"in_stock": True,
},
{
"id": 7,
"embedding": [0.09, 0.38, 0.17, 0.60, 0.27],
"name": "Runner A3",
"brand": "Brand A",
"category": "running_shoes",
"color": "black",
"price": 159.99,
"rating": 4.8,
"in_stock": True,
},
{
"id": 8,
"embedding": [0.13, 0.43, 0.21, 0.65, 0.32],
"name": "Runner A4",
"brand": "Brand A",
"category": "running_shoes",
"color": "black",
"price": 149.99,
"rating": 4.9,
"in_stock": True,
},
],
)

client.load_collection(collection_name)

query_vector = [0.11, 0.40, 0.19, 0.64, 0.30]
search_params = {
"metric_type": "COSINE",
"params": {},
}

上記のセットアップでは、ベクトルインデックスと検索パラメーターの両方に COSINE を設定します。そのため、以降の例では {"_score": "desc"} を使用して、コサイン類似度が高いものを先に配置します。L2 などの距離メトリクスの場合は、{"_score": "asc"} を使用します。

バケットの比較と並べ替え

計算された統計を使用して取得したエンティティのグループを比較し、バケットが返される順序を制御する必要がある場合は、このパターンを使用します。この例では、Zilliz Cloud は取得した商品を brand でグループ化し、各ブランドバケットの価格メトリクスを計算し、バケットを平均価格で並べ替えます。

フィールド値ごとに 1 つ以上のエンティティを返して結果の多様性を高めることだけが目的の場合は、代わりに Grouping Search を使用してください。

次の設定では、最大 3 つのブランドバケットを作成し、各バケットのメトリクスを計算し、バケットを平均価格で並べ替えます。

python
aggregation = SearchAggregation(
# Form one bucket for each distinct brand value.
fields=["brand"],
# Return up to three buckets at this aggregation level.
size=3,
# Calculate named metrics for every selected bucket.
metrics={
"product_count": {"count": "*"},
"avg_price": {"avg": "price"},
"min_price": {"min": "price"},
},
# Sort buckets by average price, highest first.
order=[
{"avg_price": "desc"},
# If average prices are equal, sort by bucket key in ascending order.
{"_key": "asc"},
],
)

このオブジェクトを MilvusClient.search()search_aggregation パラメーターに渡します。

python
result = client.search(
collection_name=collection_name,
data=[query_vector],
anns_field="embedding",
search_params=search_params,
output_fields=[
"name",
"brand",
"category",
"color",
"price",
"rating",
"in_stock",
],
search_aggregation=aggregation,
)

search_aggregation が設定されている場合、PyMilvus は result[0] に通常のエンティティヒットを返しません。代わりに、result.agg_buckets[0] からバケットレスポンスを読み取ります。output_fields パラメーターは、返される各 AggregationHit.fields マッピングに含めるスカラーフィールドを制御します。Zilliz Cloud は、output_fields にリストされていないメトリクスソースフィールドとソートフィールドを引き続き使用できます。

サンプルのバケット出力を表示

次の出力は、上記のリクエストから取得し、読みやすさのために JSON としてシリアル化したものです。PyMilvus は JSON ではなく AggregationBucket オブジェクトを返します。key の値は、fields に 1 つのフィールドしか含まれていない場合でも、常にキーコンポーネントの順序付きリストです。これにより、複合キーのフィールド順序が保持されます。

json
[
{
"key": [
{
"field_id": 103,
"field_name": "brand",
"value": "Brand B"
}
],
"count": 1,
"metrics": {
"product_count": 1,
"avg_price": 159.99,
"min_price": 159.99
},
"hits": [],
"sub_groups": []
},
{
"key": [
{
"field_id": 103,
"field_name": "brand",
"value": "Brand A"
}
],
"count": 1,
"metrics": {
"product_count": 1,
"avg_price": 129.99,
"min_price": 129.99
},
"hits": [],
"sub_groups": []
},
{
"key": [
{
"field_id": 103,
"field_name": "brand",
"value": "Brand C"
}
],
"count": 1,
"metrics": {
"product_count": 1,
"avg_price": 119.99,
"min_price": 119.99
},
"hits": [],
"sub_groups": []
}
]

このガイドの単一のクエリベクトルについては、返されたトップレベルのバケットを result.agg_buckets[0] から読み取ります。各バケットは、順序付けられたキーコンポーネント、保持された候補の count、計算された metrics、代表的な hits、および sub_groups 内のネストされたバケットを公開します。

設定は次のように読み取ります。

設定制御する内容この例では
fieldsZilliz Cloud がバケットキーを作成する方法個別の brand 値ごとに 1 つのバケットを作成します。
size返されるバケットの最大数最大 3 つのブランドバケットを返します。
metrics各バケットに対して計算される統計商品数、平均価格、最低価格を計算します。
orderZilliz Cloud が返されたバケットを並べ替える方法平均価格で並べ替え、次にバケットキーで同順位を解決します。

Zilliz Cloud は、search_aggregation が設定されている場合、limit を無視します。トップレベルのバケット数を制御するには、ルートの SearchAggregation.size 値を使用します。

これらの設定では、Zilliz Cloud は Brand B、Brand A、Brand C のバケットを avg_price の降順で返します。_key 基準は、バケットの平均価格が同じ場合にのみ適用されます。この設定では top_hits を定義していないため、すべてのバケットの hits リストは空になり、キーごとの候補バジェットは 1 になります。したがって、表示される件数とメトリクスは、ブランドごとに保持された 1 件の候補を表します。集計でより広いキーごとのメトリクスウィンドウが必要な場合は、より大きな TopHits.sizetop_hits を設定してください。

メトリクスと並べ替えのルール

SearchAggregation.metrics エントリは、ユーザー定義のエイリアスを操作とそのソースにマッピングします。

ソースサポートされる操作動作
任意の非 JSON かつ非動的フィールドcountソースフィールドが NULL でない保持候補をカウントします。
整数または浮動小数点フィールドsumavgminmaxnull でない保持値に対して計算します。
文字列または TIMESTAMPTZ フィールドminmaxnull でない保持値の最小値または最大値を選択します。
"*"countバケット内のすべての保持候補をカウントします。結果は bucket.count と一致します。
_scoresumavgminmax保持候補の ANN 類似度または距離の値を集計します。

SearchAggregation.order は次のキーを受け入れます。

順序キー意味
メトリクスエイリアス同じ集計レベルの metrics で計算された値(avg_price など)で並べ替えます。
_count各バケット内の保持候補の数で並べ替えます。
_key_key という名前のコレクションフィールドではなく、バケットキーで並べ替えます。

order エントリは、キーを "asc" または "desc" にマッピングします。Zilliz Cloud は複数のエントリを最初から最後まで評価します。order を省略した場合、Zilliz Cloud は保持された候補セットからのバケット検出順序を維持します。

ベクトルの一致品質でバケットを並べ替えるには、まず _score からバケットレベルのメトリクスを計算し、次にそのメトリクスエイリアスを order で使用します。各バケットには複数のエンティティスコアを含めることができるため、_score をバケットの順序キーとして直接使用することはできません。例えば、COSINE または IP の場合は次のようになります。

python
aggregation = SearchAggregation(
fields=["brand"],
size=3,
metrics={"max_score": {"max": "_score"}},
order=[{"max_score": "desc"}],
)

L2 の場合は、_score の最小値を計算し、メトリクスエイリアスを昇順に並べ替えて、距離が最も小さいバケットが先に来るようにします。

複合バケットキーの作成

複合バケットキーを作成するには、同じリストに複数のフィールド名を渡します。

python
aggregation = SearchAggregation(
# Combine brand and color to form a composite bucket key.
fields=["brand", "color"],
size=6,
)

この設定では、(Brand A, black)(Brand A, blue)(Brand B, white) などのキーが生成される可能性があります。2 つのエンティティが同じバケットを共有するのは、両方の値が一致する場合だけです。Zilliz Cloud はリストの順序を保持するため、brand が最初のキーコンポーネントで、color が 2 番目になります。order_key を使用すると、Zilliz Cloud は複合キーコンポーネントを同じ順序で比較します。1 つのフラットなリストに複数の文字列を渡します。ネストされたリストはサポートされていません。

size=6 は、この集計レベルで返される複合バケットの最大数です。サンプルデータには 5 つの異なるブランドと色の組み合わせが含まれるため、5 つすべてを返すことができます。返されるエントリ数の制限では、このリクエストは 1 query vector × 6 buckets × 1 = 6 の設定済み結果エントリに寄与します。

1 つの SearchAggregation.fields リスト内の複数のフィールドは、その集計レベルで複合バケットキーを作成します。親子のバケット階層を作成するには、ネストされた集計を使用します。

以降の例では aggregation を再定義します。更新されたオブジェクトを同じ search_aggregation パラメーターに渡し、検索呼び出しを再実行します。

各バケットから代表的な結果を表示

アプリケーションで各バケットから実際の商品を表示する必要がある場合は、代表的なエンティティを含めます。この例では、Zilliz Cloud は各ブランドバケットから最大 2 つの商品を、評価、次にベクトルスコアの順で返します。

TopHits を次のように設定します。

python
aggregation = SearchAggregation(
fields=["brand"],
size=3,
# Return and sort representative entities for each selected bucket.
top_hits=TopHits(
# Return up to two entities per bucket.
size=2,
# Apply sort criteria in list order.
sort=[
{"rating": "desc"},
{"_score": "desc"},
],
),
)
代表的なヒットを含むバケットを表示

次の Brand A バケットは、上記のリクエストから取得し、読みやすさのために JSON としてシリアル化したものです。

json
{
"key": [
{
"field_id": 103,
"field_name": "brand",
"value": "Brand A"
}
],
"count": 2,
"metrics": {},
"hits": [
{
"pk": 1,
"score": 0.99976646900177,
"fields": {
"brand": "Brand A",
"category": "running_shoes",
"color": "black",
"in_stock": true,
"name": "Runner A1",
"price": 129.99,
"rating": 4.7
}
},
{
"pk": 2,
"score": 0.9997048377990723,
"fields": {
"brand": "Brand A",
"category": "running_shoes",
"color": "blue",
"in_stock": true,
"name": "Trail A2",
"price": 139.99,
"rating": 4.6
}
}
],
"sub_groups": []
}
パラメーター目的
top_hits省略可能。この集計レベルの代表エンティティを設定します。省略した場合、bucket.hits は空になり、キーごとの候補バジェットはデフォルトの 1 になります。
TopHits.size選択された各バケットから最大 2 件の代表エンティティを返し、集計ツリー全体のキーごとの候補バジェットを 2 に設定します。
TopHits.sortリストされた基準を使用して、各バケット内のエンティティを並べ替えます。

アプリケーションで代表的なエンティティが必要な場合、または件数とメトリクスにより広いキーごとの候補ウィンドウが必要な場合は、top_hits を設定します。TopHits.size を大きくすると、候補バジェットと、制限事項で説明する返されるエントリの最大数の計算の両方が増加します。

SearchAggregation.order はバケットを並べ替え、TopHits.sort は各バケット内に保持されたエンティティを並べ替えます。並べ替え順序は、count とメトリクス用に保持された候補を変更しません。TopHits.sort は、サポートされている比較可能なスカラーフィールド名と、ANN の類似度または距離を表す組み込みの _score フィールドを受け入れます。Zilliz Cloud は sort エントリを最初から最後まで評価します。この例では、商品を rating の高い順に並べ、2 つの評価が等しい場合にのみ _score を使用します。セットアップでは COSINE を使用しているため、_score の降順で、より類似した商品が先に来ます。

metrics または TopHits.sort で使用されるフィールドは、output_fields に含める必要はありません。Zilliz Cloud はこれらのフィールドを内部的に取得しますが、返される各ヒットの fields マッピングに含まれるのは、output_fields に明示的にリストされたフィールドだけです。プライマリキーとベクトルスコアは、AggregationHit.pkAggregationHit.score を通じて引き続き利用できます。

返される各 AggregationHit は、プライマリキーを pk で、ベクトルスコアを score で、要求された出力フィールドを fields で公開します。

複数レベルでの結果のグループ化

あるレベルのバケットを別のレベルの中に入れる必要がある場合は、ネストされた集計を使用します。この例では、Zilliz Cloud は最初に category バケットを作成し、次に各 category 内に brand バケットを作成します。

子集計は、その親バケットに割り当てられたエンティティのみを受け取ります。fields は各集計レベルのバケットキーを制御し、sub_aggregation は親子階層を作成します。

次の設定では、キーが (running_shoes) の category バケットを作成します。その親バケット内で、子集計は (Brand A)(Brand B)(Brand C) などのキーを持つ個別の brand バケットを作成します。

plaintext
Parent bucket key:
(running_shoes)

Child bucket keys:
├── (Brand A)
├── (Brand B)
└── (Brand C)

各レベルは独立して複数のフィールドを使用できます。例えば、子集計で fields=["brand", "color"] を使用すると、(Brand A, black) などの複合子キーが作成されます。

次の設定はこの階層を実装します。

python
aggregation = SearchAggregation(
fields=["category"],
size=2,
metrics={
"product_count": {"count": "*"},
"avg_price": {"avg": "price"},
},
order=[{"product_count": "desc"}],
# For each category bucket, group only its entities by brand.
sub_aggregation=SearchAggregation(
fields=["brand"],
size=3,
metrics={
"brand_count": {"count": "*"},
"avg_rating": {"avg": "rating"},
},
order=[{"avg_rating": "desc"}],
top_hits=TopHits(
size=2,
sort=[{"rating": "desc"}],
),
),
)
ネストされたバケット結果を表示

次のシリアル化された抜粋は、running_shoes 親バケットとその Brand B 子バケットを示しています。簡潔にするため、Brand A と Brand C の子バケットは省略しています。

json
{
"key": [
{
"field_id": 104,
"field_name": "category",
"value": "running_shoes"
}
],
"count": 4,
"metrics": {
"avg_price": 137.49,
"product_count": 4
},
"hits": [],
"sub_groups": [
{
"key": [
{
"field_id": 103,
"field_name": "brand",
"value": "Brand B"
}
],
"count": 1,
"metrics": {
"avg_rating": 4.8,
"brand_count": 1
},
"hits": [
{
"pk": 3,
"score": 0.9994542598724365,
"fields": {
"brand": "Brand B",
"category": "running_shoes",
"color": "white",
"in_stock": true,
"name": "Runner B1",
"price": 159.99,
"rating": 4.8
}
}
],
"sub_groups": []
}
]
}

表示される結果は、単一の複合バケットキー (running_shoes, Brand B) ではなく、バケットパス (running_shoes) → (Brand B) を表します。

Zilliz Cloud は最初に、product_count で並べ替えて最大 2 つの category バケットを選択します。次に、選択された各 category 内で sub_aggregation を個別に実行し、avg_rating で並べ替えて最大 3 つの brand バケットを返します。

上記の出力では次のようになります。

  • ルートの running_shoes バケットには、子の複合キー全体で 4 件の保持候補が含まれます。その metrics には、ルートレベルの avg_priceproduct_count の値が含まれます。

  • ルートバケットの sub_groups リストには、子の brand バケットが含まれます。表示されている Brand B バケットには、1 件の保持候補と、それ自体の avg_rating および brand_count の値が含まれます。

  • ルート集計は top_hits を設定していないため、ルートバケットの hits リストは空です。top_hitssub_aggregation で設定されているため、Brand B の子には代表的なヒットが含まれます。

FAQ

バケットの件数とメトリクスはどの程度正確ですか?

Search Aggregation は、保持された ANN 候補を要約します。コレクション全体の集計は実行しません。

候補の保持には 2 つの近似段階があります。ANN 検索は関連するコレクションエンティティを省略する可能性があり、グループ化ステージは完全な複合キーごとに最大で最も大きな TopHits.size の候補を保持します。どのレベルでも top_hits を設定しない場合、このキーごとの制限は 1 です。

例えば、コレクションに 5,000 件の Brand A 商品が含まれ、その多くがベクトルクエリに関連しているとします。集計で TopHits(size=4) を使用する場合、Brand A バケットは完全な複合キーごとに最大 4 件の候補を保持できます。その count とメトリクスは、保持されたこれらの候補を表すものであり、関連するすべての Brand A 商品や 5,000 件のコレクションエンティティすべてを表すものではありません。

近似は、order がメトリクスエイリアスを使用する場合に最も重要になります。検索の再現率が変化するとメトリクス値が変化し、その結果、SearchAggregation.size 内に収まるバケットが変わる可能性があります。ネストされた集計では、各子レベルが親バケットで使用可能なエンティティに対して動作するため、この影響が増幅される可能性があります。

一致するすべてのエンティティに対する正確な統計が必要な場合は、Search Aggregation ではなく、正確なクエリ集計ワークフローを使用してください。

アプリケーションの主要な結果の形に基づいて選択してください。

主なニーズ推奨使用するレスポンス
グループ化フィールド内の値の重複を減らして、標準的なランク付けされたエンティティリストを返すGrouping Search各クエリベクトルのフラットな検索ヒット
キー、件数、メトリクス、順序、代表ヒット、子バケットを使用して、グループをバケットとして検査または比較するSearch Aggregationresult.agg_buckets 内の AggregationBucket オブジェクト

Search Aggregation が top_hits を設定している場合でも、その主要なレスポンスはバケットツリーのままです。Grouping Search は、アプリケーションが通常の検索ヒットをすでに処理しており、主に結果の多様性を求めている場合に引き続き役立ちます。

これらの API は相互に排他的です。PyMilvus は、同じリクエストで search_aggregationgroup_by_field または group_by_fields と組み合わせると ParamError を発生させます。