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

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

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

كيف ينطبق البحث الهجين على StructArray

AnnSearchRequest التركيبةنطاق المرشح النهائيسلوك النتيجةelement_scope
حقل متجه على مستوى المجموعة + الحقل الفرعي EmbeddingList في StructArrayمستوى الكيانيتم فهرسة المرشحين النهائيين حسب المفتاح الأساسي.لا تستخدم.
حقل متجه على مستوى المجموعة + حقل فرعي على مستوى عنصر StructArrayمستوى الكيانيتم طي النتائج على مستوى العنصر إلى مرشحين على مستوى الكيان قبل إعادة الترتيب المختلط.تكوين طي اختياري على مستوى عنصر StructArray AnnSearchRequest.
حقول فرعية متعددة على مستوى العنصر ضمن نفس حقل StructArrayمستوى العنصريتم تحديد المرشحين النهائيين باستخدام المفتاح الأساسي بالإضافة إلى إزاحة عنصر Struct.لا تستخدم.
الحقول الفرعية على مستوى العنصر ضمن حقول StructArray مختلفةمستوى الكيانلا تشترك إزاحات العناصر في الهوية، لذا يتم طي كل AnnSearchRequest على مستوى عنصر StructArray قبل إعادة الترتيب.تكوين طي اختياري لكل حقل فرعي على مستوى العنصر ( AnnSearchRequest) في StructArray.

تحذير

استخدم element_scope فقط لتكوين الطي لكائنات AnnSearchRequest على مستوى العنصر في StructArray في بحث هجين على مستوى العنصر غير المتماثل في البنية. لا تستخدمه لطلبات EmbeddingList، أو طلبات المتجهات على مستوى المجموعة، أو البحث الهجين على مستوى العنصر في StructArray المتماثل.

قبل البدء

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

المتطلباتالتفاصيل
حقل StructArrayتحتوي المجموعة على حقل StructArray مثل chunks.
الحقول الفرعية من نوع Vectorاستخدم حقول فرعية متجهة منفصلة للبحث في EmbeddingList والبحث على مستوى العناصر.
الفهارسchunks[emb_list_vector] يستخدم مقياس MAX_SIM*. يستخدم chunks[emb] مقياس متجه عادي مثل COSINE أو IP أو L2.
أداة إعادة الترتيباختر أداة إعادة ترتيب هجينة مثل RRFRanker أو أداة إعادة ترتيب أخرى يدعمها تطبيقك.

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

تشغيل البحث الهجين باستخدام طلب EmbeddingList

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

from pymilvus import AnnSearchRequest, MilvusClient, RRFRanker
from pymilvus.client.embedding_list import EmbeddingList

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

query_vector = [0.19, 0.24, 0.30, 0.37]

query_list = EmbeddingList()
query_list.add([0.12, 0.21, 0.32, 0.44])
query_list.add([0.18, 0.23, 0.29, 0.36])

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

chunk_list_req = AnnSearchRequest(
    data=[query_list],
    anns_field="chunks[emb_list_vector]",
    limit=10,
)

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

في هذا المثال، ينتج كلا كائني « AnnSearchRequest » مرشحين على مستوى الكيان. يتم فهرسة النتيجة النهائية باستخدام المفتاح الأساسي للكيان الأصلي. لا تقم بإضافة « element_scope » إلى طلب «EmbeddingList».

عندما تستهدف جميع كائنات AnnSearchRequest الحقول الفرعية المتجهة على مستوى العنصر ضمن حقل StructArray نفسه، يمكن للبحث الهجين الاحتفاظ بالمرشحين على مستوى العنصر من خلال إعادة الترتيب. هذا هو الوضع الهجين الوحيد لـ StructArray الذي تظل فيه النتائج النهائية على مستوى العنصر.

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

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,
    output_fields=[
        "doc_id",
        "title",
        "chunks[text]",
        "chunks[section]",
        "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"],
        )

يقوم كلا كائني AnnSearchRequest بالبحث في الحقول الفرعية المتجهة تحت chunks. يشير نفس الإزاحة التي تبدأ من الصفر إلى نفس عنصر Struct، لذا يمكن لأداة إعادة الترتيب الهجينة ترتيب المرشحين على مستوى العناصر مباشرةً. لا تقم بتعيين element_scope في هذا الوضع لأنه لا يتم إجراء أي طي على مستوى الكيان.

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

استخدم element_scope داخل params الخاص بـ AnnSearchRequest على مستوى عنصر StructArray عندما تحتاج إلى التحكم في كيفية طي العناصر المتطابقة المتعددة من نفس الكيان.

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

chunk_req = AnnSearchRequest(
    data=[query_vector],
    anns_field="chunks[emb]",
    param={
        "params": {
            "element_scope": {
                "collapse": {
                    "strategy": "topk_sum",
                    "topk": 3,
                },
            },
        },
    },
    limit=30,
    expr='element_filter(chunks, $[quality_score] > 0.8)',
)

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

في هذا المثال، تكون " title_req " على مستوى الكيان، لذا تكون النتيجة الهجينة النهائية أيضًا على مستوى الكيان. يعرض طلب " chunk_req " أولاً نتائج العناصر المطابقة من " chunks[emb]"، ثم يُدمج العناصر المعروضة من نفس الكيان عن طريق جمع أفضل ثلاث درجات للعناصر. إذا تم حذف " element_scope " عند الحاجة إلى الدمج على مستوى الكيان، فإن استراتيجية الدمج تكون افتراضيًا " max".

اختر استراتيجية تجميع

الاستراتيجيةالسلوكtopkمتطلبات المقياس
maxالاحتفاظ بأفضل نتيجة للعنصر الذي تم إرجاعه للكيان.غير مسموح به.أي مقياس متجه عادي مدعوم.
sumجمع جميع درجات العناصر التي تم إرجاعها للكيان.غير مسموح به.مقاييس الارتباط الإيجابي فقط، مثل IP أو COSINE.
avgمتوسط جميع درجات العناصر التي تم إرجاعها للكيان.غير مسموح به.أي مقياس متجه عادي مدعوم.
topk_sumجمع أفضل درجات العناصر التي تم إرجاعها لـ K للكيان.مطلوب ويجب أن يكون موجبًا.مقاييس الارتباط الإيجابي فقط، مثل IP أو COSINE.
topk_avgحساب متوسط أفضل درجات العناصر التي تم إرجاعها بواسطة K للكيان.مطلوب ويجب أن يكون موجبًا.أي مقياس متجه عادي مدعوم.

يستخدم "Collapse" فقط نتائج العناصر التي تم إرجاعها بواسطة مقياس " AnnSearchRequest" على مستوى عنصر StructArray. ولا يقوم بمسح كل عنصر Struct في الكيان بعد البحث باستخدام الشبكة العصبية الاصطناعية (ANN). اضبط قيمة " limit " للطلب على مستوى عالٍ بما يكفي لتوفير العناصر التي تريدها لتكون متاحة لعملية "Collapse".

إضافة عوامل التصفية والبحث في النطاق والتجميع

يمكنك إرفاق element_filter بـ AnnSearchRequest على مستوى عنصر StructArray عندما يجب تطبيق الشروط القياسية على نفس عناصر Struct التي تشارك في البحث المتجه. يمكنك أيضًا استخدام filter على المستوى الأعلى في hybrid_search() لشروط الكيان الأصلي.

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

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

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

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

القيود

  • استخدم element_scope فقط لكائنات AnnSearchRequest على مستوى عنصر StructArray التي يجب طيها إلى مرشحين على مستوى الكيان في البحث المختلط.

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

  • sum وتتطلب استراتيجيات التجميع topk_sum مقاييس ارتباط موجبة، مثل IP أو COSINE. لا تستخدمها مع L2.

  • topk_sum وتتطلب topk_avg قيمة موجبة لـ topk. ويجب ألا تتضمن استراتيجيات الطي الأخرى topk.

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

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

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

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

  • إضافة element_scope إلى طلب هجين على مستوى عنصر StructArray نفسه. يظل هذا الطلب على مستوى العنصر ولا يقوم بالطي على مستوى الكيان.

  • إضافة " element_scope " إلى " chunks[emb_list_vector]". البحث في "EmbeddingList" يكون بالفعل على مستوى الكيان.

  • افتراض أن حقلين من StructArray يشتركان في إزاحات العناصر. إن الإزاحة 3 في chunks والإزاحة 3 في حقل StructArray آخر هما عنصران مختلفان، وبالتالي يصبح الطلب الهجين على مستوى الكيان.

  • استخدام topk_sum مع L2. استخدم max أو avg أو topk_avg لمقاييس المسافة السالبة.

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

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

  1. لمعرفة وضعي البحث المتجهي الأساسيين لـ StructArray، اقرأ البحث المتجهي الأساسي باستخدام StructArray.

  2. لإضافة عوامل تصفية قياسية إلى البحث الهجين، اقرأ " البحث المُصفى باستخدام StructArray".

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

  4. لتجميع النتائج الهجينة على مستوى العنصر حسب الكيان الأصلي، اقرأ " تجميع البحث باستخدام StructArray".

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