تجميع نتائج البحثCompatible with Milvus 3.0.x
عندما يبحث المتسوق عن "أحذية جري سوداء للتدريب اليومي"، يقوم البحث عن أقرب الجيران التقريبي (ANN) بترتيب المنتجات حسب تشابه المتجهات ويعرض قائمة مسطحة بأفضل K نتائج. قد تكون النتائج ذات صلة ولكنها متكررة: في المثال أدناه، أربعة من النتائج الست الأولى هي منتجات العلامة التجارية أ، بينما تظهر العلامة التجارية ب والعلامة التجارية ج مرة واحدة لكل منهما.
لا يمكن للقائمة المسطحة أن توفر مباشرةً ملخصًا موجهًا نحو الفئات. قد يحتاج التطبيق إلى مقارنة العلامات التجارية حسب عدد المرشحين المحتفظ بهم أو متوسط السعر، أو فحص عدد صغير من المنتجات التمثيلية من كل علامة تجارية، أو تنظيم النتائج في مستويات متعددة من الفئات.
يقوم «تجميع البحث» (Search Aggregation) بتنظيم المرشحين المحتفظ بهم من شبكة الجيران (ANN) في فئات بناءً على الحقول القياسية المحددة. في هذا المثال، تصبح كل علامة تجارية فئة منفصلة. يمكن لـ Milvus حساب الإحصائيات لكل فئة، وترتيب الفئات، وإرفاق المنتجات التمثيلية. يستهلك التطبيق هذا الرد الذي يعطي الأولوية للفئات من خلال «الاستعلام المركب» ( result.agg_buckets).
تصبح نتيجة البحث المسطحة عن أحذية الجري مجموعة من فئات العلامات التجارية القابلة للمقارنة
لا يقوم «تجميع البحث» (Search Aggregation) بتشغيل تجميع دقيق للمجموعة الكاملة. يعتمد وجود المجموعات، وعددها، ومقاييسها، وترتيبها، والنتائج التمثيلية على المرشحات التي احتفظت بها مراحل الشبكة العصبية الاصطناعية (ANN) والتجميع.
كيفية العمل
يتم تجميع المرشحين من الشبكة العصبية الاصطناعية (ANN) حسب مفاتيح المجموعات ويتم إرجاعهم مع الأعداد والمقاييس والنتائج التمثيلية
استرجاع المرشحين. يقوم Milvus بتشغيل بحث الشبكة العصبية الاصطناعية (ANN) للعثور على الكيانات الأقرب إلى متجه الاستعلام. ثم تحتفظ مرحلة التجميع بعدد محدود من المرشحين لكل مفتاح مركب كامل. يمثل هذا الحد الأقصى لعدد المرشحين لكل مفتاح أكبر قيمة لـ
TopHits.sizeفي أي مكان في شجرة التجميع، أو1عندما لا يتم تكوين أي مستوى لـtop_hits.إنشاء المجموعات (buckets). يحدد
SearchAggregation.fieldsمفتاح المجموعة (bucket key). كل تركيبة فريدة من قيم الحقول تُنشئ مفتاحًا منفصلاً. في الشكل، يُنشئfields=["brand"]مفاتيح المجموعات التالية:(Brand A)و(Brand B)و(Brand C). تنتمي المرشحات المحتفظ بها التي تحمل نفس المفتاح إلى نفس المجموعة وتساهم فيcountالخاص بها. يحددSearchAggregation.sizeعدد المجموعات التي يعرضها Milvus.حساب النتائج وإرجاعها. يحتوي كل دلو مُرجع على مفتاحه وعدد المرشحين المحتفظ بهم. يمكن لـ Milvus أيضًا حساب المقاييس المُعدة مسبقًا، وترتيب الدلاء، وإرجاع الكيانات التمثيلية، وإنشاء دلاء فرعية. يعرض كل
AggregationBucketفيresult.agg_bucketskeyوcountوmetricsوhitsوsub_groups. عند تمكين «تجميع البحث» (Search Aggregation)، تكون قائمة نتائج البحث العادية فارغة.
في الرسم التخطيطي، توفر TopHits.size=4 ميزانية مرشحين لكل مفتاح تبلغ أربعة، لذا فإن المرشحين الأربعة المحتفظ بهم للعلامة التجارية «A» ينتجون count: 4. لا تعرض بطاقة العلامة التجارية «A» المكتملة سوى اثنين من النتائج التمثيلية الأربعة التي تم إرجاعها للحفاظ على إيجاز الشكل.
باستخدام sub_aggregation ، يكرر Milvus الخطوتين 2 و3 داخل كل مجموعة أصلية. يمكن أن تؤدي التغييرات في معدل الاسترجاع لشبكة ANN أو الميزانية المخصصة للمرشحين لكل مفتاح إلى تغيير عدد المجموعات والمقاييس والترتيب والنتائج والنتائج المتداخلة.
القيود
قبل استخدام تجميع البحث، يرجى ملاحظة الحدود التالية:
التجميعات المتداخلة: يمكن أن يحتوي الطلب على تجميع جذر واحد لـ
SearchAggregationوما يصل إلى ثلاثة مستويات متداخلة منsub_aggregation، بحد أقصى أربعة مستويات إجمالًا.الحقول المستخدمة لإنشاء مفاتيح المجموعات: يدعم «
SearchAggregation.fields» الحقول المنطقية (Boolean)، والأعداد الصحيحة (integer)، و«VARCHAR»، و«TIMESTAMPTZ». ولا يدعم الحقول «FLOAT»، و«DOUBLE»، و«ARRAY»، و«JSON»، و«GEOMETRY»، و«TEXT»، أو الحقول المتجهة (vector)، أو الحقول الديناميكية.الحقول المترية:
countتقبل"*"أو أي حقل غيرJSONوغير ديناميكي، وتتخطى قيمNULLعند تحديد حقل.sumوavgتقبلان الحقول الصحيحة والعائمة.minوmaxتقبلان بالإضافة إلى ذلك الحقول النصية وTIMESTAMPTZ.حقول فرز «Top Hits»: تقبل
TopHits.sortالحقول القابلة للمقارنة من نوع «Boolean» و«Integer» و«Floating-point» و«String» و«TIMESTAMPTZ»، بالإضافة إلى_score. ولا تدعمARRAYأوJSONأوGEOMETRYأو الحقول المتجهة أو الديناميكية.الميزانية المرشحة: أكبر قيمة لـ
TopHits.sizeفي أي مكان في شجرة التجميع هي أيضًا عدد المرشحين المحتفظ بهم لكل مفتاح مركب كامل. إذا لم يتم تكوينtop_hitsفي أي مستوى، يحتفظ Milvus بمرشح واحد لكل مفتاح. يتم حسابcountوالمقاييس الخاصة بالمجموعة من هذه المرشحين المحتفظ بهم، لذا فإن تغييرTopHits.sizeيمكن أن يغيرها.حقول المجموعات القابلة للقيمة الفارغة: تشكل قيمة
NULLمفتاح المجموعة الخاص بها. لاستبعاد المجموعة الفارغة، أضف مرشحًا مثلbrand is not nullإلى طلب البحث.الحقول المتكررة: لا يمكن أن يظهر الحقل نفسه في أكثر من قائمة واحدة من قوائم «
SearchAggregation.fields». على سبيل المثال، إذا كان التجميع الجذري يستخدمfields=["category"]، فلا يمكن لـ «sub_aggregation» المتداخلة أن تستخدم أيضًاfields=["category"].التركيبات غير المدعومة: لا يمكن دمج «تجميع البحث» (Search Aggregation) مع «التجميع المتكرر» (
offset) أو «مكررات البحث» (Search Iterators) أو «البحث الهجين» (Hybrid Search) أو «أداة التمييز» (Highlighter) أو «البحث التجميعي» (Grouping Search).المدخلات المرجعة: حافظ على الحد الأقصى المُعد لعدد مدخلات النتائج عند 10,000 أو أقل. احسب هذا الحد الأقصى على النحو التالي:
number of query vectors × size at every aggregation level × largest TopHits.size at any levelاستخدم «
1» كعامل أخير عندما لا يتم تكوين أي مستوى لـ «TopHits». على سبيل المثال، متجه استعلام واحد، و10 مجموعات جذرية، وخمس مجموعات فرعية لكل مجموعة جذرية، ونتيجتان لكل مجموعة فرعية، ينتج عنها الحد الأقصى المُكوّن التالي:1 × 10 × 5 × 2 = 100
استخدام تجميع البحث
اختر مثالًا بناءً على ما تريد تحقيقه:
| انتقل إلى | الوصف | الإعدادات الرئيسية |
|---|---|---|
| قارن وفرز المجموعات | احسب إحصائيات كل مجموعة على حدة لمقارنة المجموعات، ثم قم بفرز المجموعات التي تم إرجاعها حسب المقاييس أو الأعداد أو المفاتيح. | fields، size ، metrics ، order |
| عرض نتائج تمثيلية من كل مجموعة | إرجاع عدد محدود من الكيانات من كل مجموعة وفرز تلك الكيانات بشكل مستقل حسب الحقول القياسية أو النتيجة المتجهة. | top_hits، TopHits.size ، TopHits.sort |
| تجميع النتائج على مستويات متعددة | تنظيم النتائج في مستويات مجموعات رئيسية وفرعية لتحليل أبعاد متعددة بالتسلسل. | sub_aggregation |
تستخدم الأمثلة أدناه مجموعة منتجات تحتوي على حقول العلامة التجارية والفئة واللون والسعر والتقييم. جميع أسماء العلامات التجارية وأسماء المنتجات والأسعار والتقييمات ونتائج البحث هي بيانات أمثلة اصطناعية. قم بتوسيع القسم التالي لإنشاء المجموعة وتحديد متغيرات البحث المشتركة.
from pymilvus import DataType, MilvusClient, SearchAggregation, TopHits
client = MilvusClient(
uri="http://localhost:19530",
token="root:Milvus",
)
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"}.
مقارنة المجموعات وفرزها
استخدم هذا النمط عندما تحتاج إلى مقارنة مجموعات من الكيانات المسترجعة باستخدام إحصائيات محسوبة والتحكم في ترتيب إرجاع المجموعات. في هذا المثال، يقوم Milvus بتجميع المنتجات المسترجعة حسب brand ، ويحسب مقاييس السعر لكل مجموعة من العلامات التجارية، ويصنف المجموعات حسب متوسط السعر.
إذا كان هدفك هو تحسين تنوع النتائج فقط عن طريق إرجاع كيان واحد أو أكثر لكل قيمة حقل، فاستخدم «البحث المجمّع» (Grouping Search ) بدلاً من ذلك.
يُنشئ التكوين التالي ما يصل إلى ثلاث مجموعات للعلامات التجارية، ويحسب المقاييس لكل مجموعة، ويصنف المجموعات حسب متوسط السعر:
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"},
],
)
قم بتمرير الكائن إلى المعلمة search_aggregation في MilvusClient.search():
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 » مُرجع؛ ولا يزال بإمكان Milvus استخدام حقول «metric-source» و«sort» غير المدرجة في « output_fields ».
تم التقاط الناتج التالي من الطلب أعلاه وتم تسلسله بتنسيق JSON لتسهيل القراءة. يُرجع PyMilvus كائنات AggregationBucket بدلاً من JSON. تكون قيمة key دائمًا قائمة مرتبة من مكونات المفتاح، حتى عندما يحتوي fields على حقل واحد فقط. وهذا يحافظ على ترتيب الحقول للمفاتيح المركبة.
[
{
"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.
اقرأ التكوين على النحو التالي:
| الإعداد | ما يتحكم فيه | في هذا المثال |
|---|---|---|
fields | كيف يقوم Milvus بإنشاء مفاتيح المجموعات | يُنشئ دلوًا واحدًا لكل قيمة مميزة من قيم brand. |
size | الحد الأقصى لعدد المجموعات التي يتم إرجاعها | يُرجع ما يصل إلى ثلاثة باكتات للعلامة التجارية. |
metrics | الإحصائيات المحسوبة لكل مجموعة | يُحسب عدد المنتجات، ومتوسط السعر، والسعر الأدنى. |
order | كيف يقوم Milvus بفرز المجموعات التي يتم إرجاعها | يُصنف حسب متوسط السعر، ثم يستخدم مفتاح المجموعة (bucket key) لكسر التعادل. |
يتجاهل Milvus limit عند تعيين search_aggregation. استخدم قيمة الجذر SearchAggregation.size للتحكم في عدد المجموعات ذات المستوى الأعلى.
باستخدام هذه الإعدادات، يعرض Milvus مجموعات العلامات التجارية B و A و C بترتيب تنازلي وفقًا لـ avg_price. يُطبق معيار _key فقط عندما يكون للمجموعات نفس متوسط السعر. ونظرًا لأن هذا التكوين لا يحدد top_hits ، فإن قائمة hits لكل مجموعة تكون فارغة وتكون الميزانية المرشحة لكل مفتاح هي 1. وبالتالي، فإن الأعداد والمقاييس المعروضة تصف مرشحًا واحدًا محفوظًا لكل علامة تجارية. قم بتكوين top_hits بقيمة أكبر لـ TopHits.size عندما يحتاج التجميع إلى نافذة مقاييس أوسع لكل مفتاح.
يقوم كل إدخال في SearchAggregation.metrics بتعيين اسم مستعار محدد من قبل المستخدم إلى {operation: source}:
| المصدر | العمليات المدعومة | السلوك |
|---|---|---|
أي حقل غيرJSON وغير ديناميكي | count | يحسب المرشحين المحتفظ بهم الذين لا يكون حقل المصدر الخاص بهم هو NULL. |
| حقل عدد صحيح أو عدد عائم | sum، و avg ، و min ، max | يحسب القيم المحتفظ بها غير الفارغة. |
حقل من نوع سلسلة أو TIMESTAMPTZ | min، max | يختار الحد الأدنى أو الحد الأقصى للقيمة المحتفظ بها غير الفارغة. |
"*" | count | يحسب كل مرشح محتفظ به في المجموعة. تتطابق النتيجة مع bucket.count. |
_score | sum، avg ، min ، max | يجمع قيم التشابه أو المسافة وفقًا لشبكة ANN للمرشحين المحتفظ بهم. |
SearchAggregation.order يقبل المفاتيح التالية:
| مفتاح الترتيب | المعنى |
|---|---|
| اسم مستعار للمقياس | يُصنف حسب قيمة محسوبة في metrics على نفس مستوى التجميع، مثل avg_price. |
_count | يُرتب حسب عدد المرشحين المحتفظ بهم في كل دلو. |
_key | يُرتب حسب مفتاح المجموعة بدلاً من حقل المجموعة المسمى _key. |
يقوم كل إدخال في order بتعيين مفتاح إلى "asc" أو "desc". يقوم Milvus بتقييم الإدخالات المتعددة من الأول إلى الأخير. إذا حذفت order ، فسيحتفظ Milvus بترتيب اكتشاف المجموعات من مجموعة المرشحين المحتفظ بهم.
لفرز المجموعات حسب جودة مطابقة المتجهات، احسب أولاً مقياسًا على مستوى المجموعة من _score ، ثم استخدم الاسم المستعار للمقياس في order. لا يمكنك استخدام _score مباشرةً كمفتاح لترتيب المجموعات لأن كل مجموعة يمكن أن تحتوي على عدة درجات للكيانات. على سبيل المثال، مع COSINE أو IP:
aggregation = SearchAggregation(
fields=["brand"],
size=3,
metrics={"max_score": {"max": "_score"}},
order=[{"max_score": "desc"}],
)
باستخدام L2 ، احسب الحد الأدنى لقيمة _score وقم بفرز الاسم المستعار للمقياس بترتيب تصاعدي بحيث تأتي المجموعات ذات المسافة الأقل أولاً.
لإنشاء مفتاح دلو مركب، قم بتمرير أسماء حقول متعددة في نفس القائمة:
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). لا تشترك كيانان في نفس المجموعة إلا عندما تتطابق القيمتان. يحافظ Milvus على ترتيب القائمة، لذا فإن brand هو المكون الأول للمفتاح و color هو المكون الثاني. عند استخدام _key في order ، يقارن Milvus مكونات المفتاح المركب بنفس الترتيب. قم بتمرير سلاسل متعددة في قائمة مسطحة واحدة؛ لا يتم دعم القوائم المتداخلة.
size=6 هو الحد الأقصى لعدد المجموعات المركبة التي يتم إرجاعها في مستوى التجميع هذا. تحتوي البيانات المثال على خمسة تركيبات مميزة للعلامة التجارية واللون، لذا يمكن إرجاع الخمسة جميعًا. في حد الإدخالات المرجعة، يساهم هذا الطلب بـ 1 query vector × 6 buckets × 1 = 6 إدخالات النتائج المُعدة.
تؤدي الحقول المتعددة في قائمة واحدة SearchAggregation.fields إلى إنشاء مفتاح مجموعة مركب في مستوى التجميع هذا. لإنشاء تسلسل هرمي للمجموعات بين الأصل والفرع، استخدم التجميع المتداخل.
تعيد الأمثلة التالية تعريف aggregation. قم بتمرير الكائن المحدث إلى نفس المعلمة search_aggregation وأعد تشغيل استدعاء البحث.
عرض نتائج تمثيلية من كل مجموعة
قم بتضمين الكيانات التمثيلية عندما يحتاج التطبيق إلى عرض المنتجات الفعلية من كل مجموعة. في هذا المثال، يعرض Milvus ما يصل إلى منتجين من كل مجموعة علامة تجارية، مرتبة حسب التقييم ثم حسب درجة المتجه.
قم بتكوين TopHits على النحو التالي:
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"},
],
),
)
تم التقاط مجموعة العلامة التجارية «A» التالية من الطلب أعلاه وتم تسلسلها بتنسيق 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 " يكون فارغًا وتصبح الميزانية المرشحة لكل مفتاح هي "واحد" بشكل افتراضي. |
TopHits.size | تُرجع ما يصل إلى كيانين تمثيليين من كل مجموعة محددة وتُعيّن الميزانية المرشحة لكل مفتاح على اثنين لشجرة التجميع بأكملها. |
TopHits.sort | ترتيب الكيانات داخل كل مجموعة باستخدام المعايير المذكورة. |
قم بتكوين « top_hits » عندما يحتاج التطبيق إلى كيانات تمثيلية أو عندما تحتاج الأعداد والمقاييس إلى نافذة مرشحة أوسع لكل مفتاح. يؤدي تكبير « TopHits.size » إلى زيادة كل من الميزانية المرشحة والحد الأقصى لحساب الإدخالات المرجعة في «Limits».
SearchAggregation.order يقوم بفرز المجموعات (buckets)، بينما يقوم " TopHits.sort " بفرز الكيانات المحتفظ بها داخل كل مجموعة. لا يغير ترتيب الفرز الكيانات المرشحة التي تم الاحتفاظ بها لـ " count " والمقاييس. يقبل " TopHits.sort " أسماء الحقول العددية القابلة للمقارنة المدعومة والحقل المدمج " _score "، الذي يمثل تشابه أو مسافة الشبكة العصبية الاصطناعية (ANN). يقوم Milvus بتقييم إدخالات " sort " من الأول إلى الأخير. في هذا المثال، يتم ترتيب المنتجات حسب rating من الأعلى إلى الأدنى، ولا يتم استخدام _score إلا عندما يتساوى تقييمان. ونظرًا لأن الإعداد يستخدم COSINE ، فإن الترتيب التنازلي _score يضع المنتج الأكثر تشابهًا في المرتبة الأولى.
لا يلزم أن تظهر الحقول المستخدمة بواسطة metrics أو TopHits.sort في output_fields. يقوم Milvus باسترداد هذه الحقول داخليًا، ولكن يتم تضمين الحقول المذكورة صراحةً في output_fields فقط في تعيين fields لكل نتيجة يتم إرجاعها. تظل المفاتيح الأساسية ودرجات المتجهات متاحة من خلال AggregationHit.pk و AggregationHit.score.
يكشف كل AggregationHit الذي يتم إرجاعه عن مفتاحه الأساسي في pk ، ودرجة المتجه في score ، وحقول الإخراج المطلوبة في fields.
تجميع النتائج على مستويات متعددة
استخدم التجميع المتداخل عندما تحتاج إلى مستوى واحد من المجموعات داخل مستوى آخر. في هذا المثال، يقوم Milvus بإنشاء مجموعات الفئات أولاً، ثم يقوم بإنشاء مجموعات العلامات التجارية داخل كل فئة.
لا يتلقى التجميع الفرعي سوى الكيانات المخصصة لمجموعة التجميع الأصلية. يتحكم fields في مفتاح مجموعة التجميع في كل مستوى من مستويات التجميع، بينما ينشئ sub_aggregation التسلسل الهرمي بين الأصل والفرع.
يُنشئ التكوين أدناه مجموعة فئة بمفتاح (running_shoes). داخل تلك المجموعة الأم، يُنشئ التجميع الفرعي مجموعات علامات تجارية منفصلة بمفاتيح مثل (Brand A) و (Brand B) و (Brand C).
Parent bucket key:
(running_shoes)
Child bucket keys:
├── (Brand A)
├── (Brand B)
└── (Brand C)
يمكن لكل مستوى استخدام حقول متعددة بشكل مستقل. على سبيل المثال، سيؤدي استخدام fields=["brand", "color"] في التجميع الفرعي إلى إنشاء مفاتيح فرعية مركبة مثل (Brand A, black).
التكوين التالي ينفذ هذا التسلسل الهرمي:
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 للاختصار.
{
"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).
يختار Milvus أولاً ما يصل إلى دلاء فئة اثنين، مرتبة حسب product_count. ثم يقوم بتشغيل sub_aggregation بشكل مستقل داخل كل فئة مختارة ويعرض ما يصل إلى ثلاثة دلاء للعلامات التجارية، مرتبة حسب avg_rating.
في الناتج أعلاه:
- تحتوي فئة الجذر
running_shoesعلى أربعة مرشحين محتفظ بهم عبر مفاتيحها المركبة الفرعية. وتحتوي فئةmetricsالخاصة بها على قيم المستوى الجذريavg_priceوproduct_count. - تحتوي قائمة
sub_groupsالخاصة بالحاوية الجذرية على الحاويات الفرعية للعلامات التجارية. تحتوي الحاوية المعروضة Brand B على مرشح واحد محفوظ وقيمتيavg_ratingوbrand_countالخاصتين بها. - قائمة
hitsالخاصة بالحاوية الجذرية فارغة لأن التجميع الجذري لا يقوم بتكوينtop_hits. تحتوي الحاوية الفرعية للعلامة التجارية B على نتيجة مطابقة تمثيلية لأنtop_hitsتم تكوينه فيsub_aggregation.
الأسئلة الشائعة
ما مدى دقة أعداد المجموعات والمقاييس؟
يلخص تجميع البحث المرشحين المحتفظ بهم من شبكة ANN. ولا يقوم بتشغيل تجميع للمجموعة الكاملة.
يتم الاحتفاظ بالمرشحين عبر مرحلتين تقريبيتين. قد يتجاهل بحث الشبكة العصبية الاصطناعية (ANN) كيانات المجموعة ذات الصلة، وتحتفظ مرحلة التجميع بأكبر عدد من المرشحين TopHits.size لكل مفتاح مركب كامل. إذا لم يتم تكوين أي مستوى لـ top_hits ، فإن هذا الحد لكل مفتاح هو واحد.
على سبيل المثال، لنفترض أن مجموعة تحتوي على 5,000 منتج من العلامة التجارية «A» وأن العديد منها ذو صلة باستعلام المتجه. إذا استخدم التجميع TopHits(size=4) ، فيمكن لمجموعة العلامة التجارية «A» الاحتفاظ بأربعة مرشحين كحد أقصى لمفتاح مركب كامل. ويصف كل من count والمقاييس تلك المرشحات المحتفظ بها، وليس جميع منتجات العلامة التجارية «A» ذات الصلة ولا جميع كيانات المجموعة البالغ عددها 5,000.
يكون التقريب أكثر أهمية عندما يستخدم التجميع « order » اسمًا مستعارًا للمقياس. يمكن أن تؤدي التغييرات في معدل استرجاع البحث إلى تغيير قيم المقاييس، وبالتالي تغيير المجموعات التي تتناسب مع « SearchAggregation.size ». يمكن أن يؤدي التجميع المتداخل إلى تضخيم هذا التأثير لأن كل مستوى فرعي يعمل على الكيانات المتاحة في المجموعة الأم.
إذا كنت بحاجة إلى إحصائيات دقيقة عن كل كيان مطابق، فاستخدم سير عمل تجميع الاستعلام الدقيق بدلاً من تجميع البحث.
كيف يختلف «تجميع البحث» عن «البحث التجميعي»؟
اختر بناءً على الشكل الأساسي لنتائج التطبيق:
| الحاجة الأساسية | الخيار المفضل | الاستجابة المطلوبة |
|---|---|---|
| إرجاع قائمة كيانات مرتبة بشكل قياسي مع عدد أقل من القيم المتكررة في حقل التجميع | البحث المجمّع | نتائج البحث المسطحة لكل متجه استعلام |
| فحص المجموعات أو مقارنتها كأوعية، باستخدام المفاتيح، أو الأعداد، أو المقاييس، أو الترتيب، أو النتائج التمثيلية، أو الأوعية الفرعية | تجميع البحث | AggregationBucket في result.agg_buckets |
حتى عندما يقوم تجميع البحث بتكوين top_hits ، تظل استجابته الأساسية عبارة عن شجرة مجموعات. يظل البحث التجميعي مفيدًا عندما يقوم التطبيق بالفعل بمعالجة نتائج البحث العادية ويريد في المقام الأول تنوع النتائج.
تتعارض واجهات برمجة التطبيقات (APIs) مع بعضها البعض. يرفع PyMilvus استثناءً من نوع « ParamError » عندما يتم دمج « search_aggregation » مع « group_by_field » أو « group_by_fields » في نفس الطلب.