تجميع نتائج البحث باستخدام StructArray

استخدم هذه الصفحة لتجميع نتائج البحث على مستوى عناصر StructArray حسب الكيان الأصلي. يمكن أن يُرجع البحث على مستوى العناصر عدة نتائج من نفس الكيان عندما تتطابق عدة عناصر Struct مع الاستعلام. يؤدي التجميع إلى طي نتائج العناصر هذه بحيث يظهر كل كيان أصلي مرة واحدة على الأكثر.

تستخدم هذه الصفحة المجموعة « tech_articles » من «إنشاء حقل StructArray». تحتوي المجموعة على حقل StructArray باسم « chunks ». يتم فهرسة الحقل الفرعي « chunks[emb] » للبحث على مستوى العناصر باستخدام مقياس متجه عادي.

كيفية تطبيق التجميع على StructArray

وضع البحثسلوك التجميعسلوك النتائج
البحث في EmbeddingListغير مدعوم.غير قابل للتطبيق.
البحث على مستوى العناصرمدعوم من خلال التجميع على المفتاح الأساسي.يُرجع نتيجة واحدة كحد أقصى لكل كيان أبوي. يتم الاحتفاظ بالبيانات الوصفية على مستوى العنصر، لذا يمكن إرجاع فهرس العنصر المحدد أو الإزاحة عند عرضها بواسطة واجهة برمجة التطبيقات (API) أو مجموعة أدوات تطوير البرامج (SDK).
البحث المختلطيتم دعمه فقط عندما تستهدف جميع عمليات البحث الفرعية حقول متجهة على مستوى العنصر ضمن حقل StructArray نفسه.يتم تجميع عمليات البحث الفرعية على مستوى العنصر حسب المفتاح الأساسي قبل معالجة النتيجة النهائية.

استخدم التجميع عندما يُرجع البحث على مستوى العنصر غير المجمّع عددًا كبيرًا جدًّا من الكيانات الأصلية المكررة. إذا كنت تريد أن يُعامل كل عنصر Struct مطابق على أنه نتيجة فردية، فاستخدم «البحث المتجه الأساسي» مع StructArray بدون group_by_field.

قبل البدء

قم بإعداد المجموعة والبيانات والفهارس قبل تشغيل البحث المجمّع.

المتطلباتالتفاصيل
الحقل الفرعي المتجه على مستوى العنصراستخدم حقل فرعي متجه من نوع StructArray مثل chunks[emb] ، مفهرسًا باستخدام مقياس متجه عادي.
استعلام متجه عادياستخدم متجه استعلام عادي، وليس EmbeddingList.
تجميع المفتاح الأساسياستخدم المفتاح الأساسي للمجموعة كـ group_by_field ، مثل doc_id.
عدم استخدام معلمات النطاقلا تقم بدمج البحث التجميعي مع معلمات البحث عن النطاق مثل radius أو range_filter.

لإعداد الفهرس، راجع حقول StructArray في الفهرس.

يبحث المثال التالي في الأجزاء الفردية أولاً، ثم يجمع نتائج العناصر حسب المفتاح الأساسي للكيان الأصلي.

from pymilvus import MilvusClient

client = MilvusClient(
    uri="http://localhost:19530",
    token="root:Milvus",
)

query_vector = [0.19, 0.24, 0.30, 0.37]

results = client.search(
    collection_name="tech_articles",
    data=[query_vector],
    anns_field="chunks[emb]",
    limit=5,
    group_by_field="doc_id",
    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"],
        )

بدون التجميع، يمكن أن يظهر نفس doc_id عدة مرات إذا كانت هناك عدة أجزاء تتطابق مع الاستعلام. مع group_by_field="doc_id" ، يظهر كل كيان أب مرة واحدة على الأكثر. يحافظ التجميع على البيانات الوصفية على مستوى العنصر، لذا يمكن أن تتضمن النتيجة المجمعة مؤشر عنصر Struct المحدد أو الإزاحة عندما تكشفها واجهة برمجة التطبيقات (API) أو حزمة تطوير البرامج (SDK).

إضافة عوامل تصفية قياسية

يمكنك الجمع بين البحث المجمّع وتصفية StructArray القياسية. استخدم element_filter عندما يجب أن يقيد الشرط القياسي عناصر Struct التي تشارك في البحث المتجهي على مستوى العناصر.

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]",
    filter=filter_expr,
    limit=5,
    group_by_field="doc_id",
    output_fields=[
        "doc_id",
        "title",
        "category",
        "chunks[text]",
        "chunks[section]",
        "chunks[quality_score]",
    ],
)

يختار المسند ذو المستوى الأعلى الكيانات المرشحة. ويقصر مسند element_filter البحث المتجهي على مستوى العنصر على عناصر Struct المطابقة. ثم يقوم التجميع بطي نتائج العناصر المطابقة حسب المفتاح الأساسي.

يُعد التجميع الهجين باستخدام StructArray ميزة على مستوى العنصر. ولا يتم دعمه إلا عندما تستهدف جميع عمليات البحث الفرعية حقول متجهات على مستوى العنصر ضمن حقل StructArray نفسه. لا تستخدم الطلبات على مستوى EmbeddingList في البحث الهجين المجمّع باستخدام StructArray.

يفترض المثال التالي أن حقل StructArray chunks يحتوي على حقلين فرعيين متجهين على مستوى العنصر، وهما chunks[emb] و chunks[code_emb] ، وكلاهما مفهرس بمقاييس متجهة عادية.

from pymilvus import AnnSearchRequest, RRFRanker

index_chunk_req = AnnSearchRequest(
    data=[query_vector],
    anns_field="chunks[emb]",
    limit=10,
    expr='element_filter(chunks, $[section] == "index")',
)

code_chunk_req = AnnSearchRequest(
    data=[code_query_vector],
    anns_field="chunks[code_emb]",
    limit=10,
    expr='element_filter(chunks, $[has_code] == true)',
)

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

في هذا المثال، تستهدف كلتا الطلبات الفرعية حقول متجهة على مستوى العنصر ضمن نفس حقل StructArray، chunks. لا يدعم البحث الهجين التجميع على مستوى العنصر إذا كان يخلط بين حقول متجهة عادية، أو حقول StructArray مختلفة، أو طلبات على مستوى EmbeddingList.

تفسير النتائج المجمعة

عنصر النتيجةالمعنى
idالمفتاح الأساسي للكيان الأصلي المجمّع.
distance أو النتيجةالنتيجة أو المسافة لعنصر Struct المحدد لذلك الكيان الأصلي.
offsetالموضع الذي يبدأ من الصفر لعنصر Struct المحدد عند إرجاعه.
المفاتيح الأساسية المتكررةغير متوقع عند التجميع حسب المفتاح الأساسي.
limitينطبق على نتائج الكيانات الأصلية المجمعة.

القيود

  • لا ينطبق البحث بالتجميع إلا على البحث المتجهي في StructArray على مستوى العنصر. لا يدعم البحث في EmbeddingList والبحث الهجين على مستوى EmbeddingList التجميع.

  • استخدم المفتاح الأساسي على النحو التالي: group_by_field. لا يُعد التجميع على مستوى عناصر StructArray عملية تجميع عامة الغرض عبر حقول قياسية عشوائية.

  • لا تقم بدمج البحث التجميعي مع البحث النطاقي.

  • لا تستخدم استعلام EmbeddingList أو مقياس MAX_SIM* للبحث المجمّع.

  • يتم دعم التجميع الهجين فقط عندما تستهدف جميع عمليات البحث الفرعية حقول متجهة على مستوى العنصر ضمن نفس حقل StructArray.

  • لا يتم دعم التجميع الهجين عندما يخلط البحث الهجين بين حقل متجه عادي، أو حقل StructArray مختلف، أو طلب على مستوى EmbeddingList.

الأخطاء الشائعة

  • استخدام التجميع مع chunks[emb_list_vector] ، وهو مخصص للبحث في EmbeddingList.

  • التجميع حسب حقل قياسي غير مفتاح أساسي.

  • التجميع حسب حقول متعددة. لا يدعم التجميع على مستوى العناصر في StructArray سوى التجميع حسب المفتاح الأساسي.

  • توقع أن تمثل النتائج المجمعة كل عنصر Struct مطابق. يعرض التجميع نتيجة واحدة على الأكثر لكل كيان أب.

  • الافتراض بأن البحث المجمّع على مستوى العناصر يعيد حساب درجة " MAX_SIM* " بنمط EmbeddingList. يؤدي التجميع إلى طي النتائج المطابقة على مستوى العناصر؛ ولا يغير نموذج التقييم.

  • الجمع بين group_by_field و radius أو range_filter.

الخطوات التالية

  1. لتعلم البحث على مستوى العناصر غير المجمعة أولاً، اقرأ «البحث المتجهي الأساسي باستخدام StructArray».

  2. لإضافة مرشحات قياسية إلى البحث المجمّع، اقرأ «البحث المُصفى باستخدام StructArray».

  3. لاستخدام حدود التقييم أو المسافة بدلاً من التجميع، اقرأ «البحث في النطاق باستخدام StructArray».

  4. للتحقق من حدود البحث في StructArray، اقرأ «حدود StructArray».