التوافق بين الأعضاءCompatible with Milvus v3.0.2+
نظرة عامة
يقوم مرشح مطابقة العضوية بتصفية الكيانات عن طريق اختبار ما إذا كانت قيمة الحقل القياسي تنتمي إلى مجموعة مقدمة من قبل المستدعي. يقوم العميل بإنشاء كتلة ثنائية مدمجة لمرشح العضوية ويمررها كقيمة قالب تعبير.
وهي تحل محل قوائم " IN [...] " الكبيرة. يقوم مرشح " IN " بتسلسل كل عضو في الطلب، لذا يمكن أن تتجاوز مجموعات الأعضاء الكبيرة بما يكفي حد الاستلام الخاص بـ gRPC للوكيل. باستخدام " membership_match"، يقوم الوكيل بالتحقق من صحة الكتلة وتضمينها في خطة الاستعلام دون إعادة إنشاء قائمة الأعضاء.
سير عمل مطابقة العضوية: يقوم العميل بإنشاء blob قابل لإعادة الاستخدام، ويقوم الوكيل بالتحقق من صحته، وتقوم QueryNodes بتقييمه.
يوضح الرسم البياني تقسيم العمل الثابت. يقوم العميل بإنشاء الكتلة مرة واحدة وإعادة استخدامها عبر الطلبات؛ ويقوم الوكيل بالتحقق من صحة حدود الغلاف والحجم ويدمج الكتلة في خطة الاستعلام حرفياً؛ وتقوم QueryNodes بتقييم الخطة مقابل البيانات الأولية أو الفهرس.
يحتوي المشغل على نوعين من الترميز مع ضمانات صحة مختلفة:
- Bloom (
type=bloom): عضوية تقريبية. من الممكن حدوث نتائج إيجابية خاطئة؛ ولا يُتوقع حدوث نتائج سلبية خاطئة من مرشح صالح. الاستخدام النموذجي: مرشحات الجمهور ذات الحجم الكبير أو مرشحات الاستبعاد حيث تكون النتائج الإيجابية الخاطئة العرضية مقبولة. - Roaring (
type=roaring): عضوية دقيقة للقيم الصحيحة. الاستخدام النموذجي: قوائم التحكم في الوصول (ACL)، ورؤية المستأجرين، وفلاتر الامتثال، وعمليات الحذف حسب مجموعة المعرفات.
لا تستخدم عضوية بلوم لاتخاذ قرارات التفويض أو عمليات الحذف المدمرة. قد تؤدي نتيجة إيجابية خاطئة إلى كشف كيان أو حذف كيان غير موجود في المجموعة المقصودة.
قائمة مراجعة تشغيلية
- تأكد من نوع الحقل المستهدف وقم بإنشاء blob من نفس مجال القيم هذا.
- اختر «بلوم» فقط عندما تكون النتائج الإيجابية الخاطئة مقبولة.
- اختر Roaring لقوائم التحكم في الوصول (ACL)، والامتثال، وعزل المستأجرين، وعمليات الحذف.
- قم بإنشاء blobs كبيرة مرة واحدة وأعد استخدامها؛ لا تقم بإعادة إنشائها داخل كل طلب.
- حدد حجم الكتلة (blob) بالبايتات المتسلسلة، وليس بعدد العناصر المكونة لها.
- في الكتلة ذات الإصدارات المختلطة، أكمل الترقية التدريجية، بالبدء بالوكلاء أولاً، قبل تمكين "
membership_match". - اختبر التعبير على مجموعة غير إنتاجية قبل تمكين سير عمل تدميري.
بناء جملة التعبير
membership_match(<field>, {<template>}, type=bloom)
membership_match(<field>, {<template>}, type=roaring)
membership_match(<field>, {<template>})
not membership_match(<field>, {<template>}, type=bloom)
الحجة الثانية هي عنصر نائب في القالب. توفر حزمة SDK قيمة العنصر النائب كملف protobuf bytes الذي يحتوي على كتلة التصفية التي أنشأها العميل. اجعل type صريحًا في تعبيرات الإنتاج حتى يكون عقد الصحة المقصود مرئيًا في الكود والسجلات.
الحجة type اختيارية. كل blob يحمل رأسًا سحريًا ذاتي الوصف، MBF1 لـ Bloom و MRB1 لـ Roaring، ويقوم الخادم باستكشاف الرأس عند حذف type. يتم رفض type الصريح الذي يتعارض مع رأس blob كخطأ في الطلب، وتؤدي الرؤوس غير المعروفة أو المقطوعة إلى حالة فشل مغلقة.
اختر الترميز
استخدم «بلوم» (Bloom) عندما تكون النتائج الإيجابية الخاطئة مقبولة. يقبل «بلوم» الحقول الصحيحة الموقعة (INT8/16/32/64)، وحقول VARCHAR، ومسارات JSON. مرشح «بلوم» ليس قائمة سماح دقيقة.
fpr (معدل الإيجابيات الكاذبة) هو احتمال أن يبلغ مرشح Bloom عن قيمة ما على أنها عضو في حين أن القيمة لم تُدرج مطلقًا: fpr=0.005 يعني تقريبًا أن قيمة واحدة غير عضو من بين كل 200 قيمة يتم الإبلاغ عنها خطأً على أنها موجودة. يؤدي معدل إيجابيات كاذبة (fpr) أقل إلى إنتاج blob أكبر.
استخدم Roaring عندما يجب أن تكون كل مطابقة دقيقة. يقبل Roaring الحقول الصحيحة الموقعة فقط؛ يتم تمديد إشارة العناصر إلى INT64 قبل التسلسل، لذا فإن INT8 -1 وINT64 -1 هما نفس العنصر. لا تستخدمه مع UUID أو حقول السلاسل الأخرى.
| البعد | Bloom (type=bloom) | Roaring (type=roaring) |
|---|---|---|
| الدقة | تقريبي؛ احتمال وجود نتائج إيجابية خاطئة؛ لا توجد نتائج سلبية خاطئة | دقيق؛ لا توجد نتائج إيجابية خاطئة ولا نتائج سلبية خاطئة |
| الحقول | INT8/16/32/64، VARCHAR، مسارات JSON | INT8/16/32/64 الموقّعة فقط |
| حجم blob | عدد العناصر ومعدل الخطأ الإيجابي (FPR)؛ حوالي 11 بت لكل عنصر عند معدل خطأ إيجابي (FPR) يبلغ 0.005؛ هيكل على شكل قوة اثنين | توزيع القيم؛ يتم ضغط المجموعات الكثيفة إلى أحجام أصغر بكثير؛ تصل القيم العشوائية ذات 64 بت إلى الحد الأقصى للحاوية البالغ 262,144 |
| الحذف | مرفوض في وقت التحليل | مسموح |
| الاستخدام النموذجي | مرشحات الجمهور والاستبعاد | قائمة التحكم في الوصول (ACL)، الامتثال، عزل المستأجر، الحذف حسب مجموعة المعرفات |
مساراتJSON مكتوبة بشكل صارم، صفًا بصف: يتم فحص سلسلة JSON كقيمة VARCHAR ، والعدد الصحيح في JSON كقيمة INT64 ، ولا يتطابق عدد مزدوج في JSON أبدًا مع عنصر عدد صحيح، على عكس IN الدقيق، حيث 5.0 يساوي 5. إذا كان المبرمجون يقومون بترميز الأعداد الصحيحة بتنسيق عائم، فقم بتوحيدها عند الكتابة أو استخدم حقلًا عدديًا محدد النوع.
في كلتا الحالتين، قم ببناء مجموعة العناصر من نفس مجال القيم الخاص بالحقل الهدف. لا تقم بإنشاء مرشح بلوم (Bloom filter) من السلسلة "10086" وتطبيقه على حقل INT64. يسجل رأس الكتلة (blob) مجالات القيم التي تم إدراجها، ويتم رفض الكتلة ذات المجال الخاطئ من قبل الوكيل (proxy) مع ظهور خطأ في المعلمة بدلاً من عدم المطابقة بصمت. أعد استخدام الكتلة التي تم إنشاؤها عبر الطلبات بدلاً من إعادة إنشائها لكل استعلام.
بالنسبة للمجموعات التي تضم بضعة آلاف من العناصر أو أقل، يظل الترميز العادي IN هو الخيار الأبسط. لا يختار الخادم بين IN وBloom وRoaring. تقع مسؤولية اختيار الترميز على عاتق المستدعي.
لاختيار الترميز:
- حدد ما إذا كان عبء العمل يتحمل النتائج الإيجابية الخاطئة. إذا لم يكن الأمر كذلك، فلا يُعد Bloom خيارًا أبدًا.
- للتحديد الدقيق للعضوية، استخدم Roaring مع حقل عدد صحيح موقّع. يتم ضغط القيم الكثيفة أو المجمعة إلى أصغر blobs.
- تحقق من حدود الحجم. قد تتجاوز القيم العشوائية الموحدة ذات 64 بت الحد الأقصى للحاوية البالغ 262,144 أو حدود الحجم. إذا حدث ذلك، فاستخدم قائمة IN تقليدية تتناسب مع حدود الطلب.
- للحصول على عضوية دقيقة في الحقول غير الصحيحة، استخدم IN. لا يوجد ترميز عضوية دقيق لهذه الحقول.
مطابقة العضوية غير متاحة عبر واجهة برمجة التطبيقات (API) RESTful HTTP. تقبل معلمات قوالب تعبيرات HTTP القيم من نوع bool و number و string و array فقط؛ ولا يوجد نوع ثنائي bytes للكتلة (blob). استخدم SDK قائمًا على gRPC لتمرير كتل العضوية.
أنماط طلبات SDK
تركز المقتطفات التالية على إنشاء blobs للعضوية وتمريرها كمعلمات لقوالب التصفية. وتفترض هذه المقتطفات أن المجموعات والحقول موجودة بالفعل وتم تحميلها، وأن عملاء SDK متصلون، وأن متجهات الاستعلام وقوائم الأعضاء والمتغيرات المرجعية الأخرى محددة. تم حذف إعداد المجموعة والهيكل الأساسي الكامل للتطبيق.
from pymilvus import MilvusClient, build_bloom_filter, build_roaring_bitmap
client = MilvusClient(uri="http://localhost:19530")
bloom_blob = build_bloom_filter(["creator-a", "creator-b"], fpr=0.005)
client.search(collection_name="posts", data=[query_vector], anns_field="embedding", limit=10,
filter="membership_match(creator_id, {members}, type=bloom)",
filter_params={"members": bloom_blob})
roaring_blob = build_roaring_bitmap([1001, 1002, 1003])
client.query(collection_name="docs", filter="membership_match(user_id, {members}, type=roaring)",
filter_params={"members": roaring_blob}, output_fields=["user_id", "title"])
bloomBlob, err := milvusclient.NewBloomFilterBlob([]int64{1001, 1002}, fpr)
if err != nil { return err }
search := milvusclient.NewSearchOption("posts", topK, vectors).
WithFilter("membership_match(creator_id, {members}, type=bloom)").
WithTemplateParam("members", bloomBlob)
roaringBlob, err := milvusclient.NewRoaringBitmapBlob([]int64{1001, 1002})
if err != nil { return err }
query := milvusclient.NewQueryOption("docs").
WithFilter("membership_match(user_id, {members}, type=roaring)").
WithTemplateParam("members", roaringBlob)
byte[] bloomBlob = BloomFilterUtils.buildBloomFilter(userIds, BloomFilterUtils.DEFAULT_FPR);
QueryReq request = QueryReq.builder().collectionName("docs")
.filter("membership_match(user_id, {members}, type=bloom)")
.filterTemplateValues(Collections.singletonMap("members", bloomBlob)).build();
byte[] roaringBlob = RoaringBitmapUtils.buildRoaringBitmap(userIds);
const bloomBlob = buildBloomFilter(userIds);
await client.query({ collection_name: 'docs',
filter: 'membership_match(user_id, {members}, type=bloom)',
exprValues: { members: bloomBlob } });
const roaringBlob = buildRoaringBitmap(integerIds);
الحذف باستخدام Roaring
استخدم كتلة Roaring دقيقة عند حذف الكيانات المحددة بواسطة مجموعة معرّفات صحيحة خارجية. راجع مجموعة الأعضاء ونوع حقل المجموعة قبل إصدار أمر الحذف. لا تستخدم Bloom: فالعضوية التقريبية ليست مسند حذف آمن، ويتم رفض أشكال Bloom في تعبيرات الحذف عند وقت التحليل.
roaring_blob = build_roaring_bitmap([1001, 1002, 1003])
client.delete(collection_name="docs", filter="membership_match(id, {members}, type=roaring)",
filter_params={"members": roaring_blob})
roaringBlob, err := milvusclient.NewRoaringBitmapBlob([]int64{1001, 1002, 1003})
if err != nil { return err }
_, err = client.Delete(ctx, milvusclient.NewDeleteOption("docs").
WithExpr("membership_match(id, {members}, type=roaring)").
WithTemplateParam("members", roaringBlob))
byte[] roaringBlob = RoaringBitmapUtils.buildRoaringBitmap(userIds);
DeleteReq request = DeleteReq.builder().collectionName("docs")
.filter("membership_match(id, {members}, type=roaring)")
.filterTemplateValues(Collections.singletonMap("members", roaringBlob)).build();
const roaringBlob = buildRoaringBitmap(integerIds);
await client.delete({ collection_name: 'docs',
filter: 'membership_match(id, {members}, type=roaring)',
exprValues: { members: roaringBlob } });
تتبع دلالات الحذف مطابقة دقيقة ثلاثية القيم:
| قيمة الحقل | membership_match(…) | ليس membership_match(…) |
|---|---|---|
| NULL | لا توجد مطابقة (NULL) | لا توجد مطابقة (NULL) |
| في مجموعة الأعضاء | تطابق | لا توجد مطابقة |
| خارج المجموعة | لا توجد مطابقة | تطابق |
يُقرأ الجدول صفًا بصف: تعمل عملية الحذف باستخدام membership_match على إزالة الكيانات الموجودة داخل المجموعة، بينما تعمل عملية الحذف باستخدام not membership_match على إزالة الكيانات الموجودة خارج المجموعة، وتبقى الكيانات ذات القيمة NULL في كلتا الحالتين.
- لا يتم حذف الكيانات ذات قيمة الحقل NULL أبدًا، في أي من الحالتين.
- لا تحذف الصورة النقطية الفارغة أي شيء. يحذف "
not membership_match(<field>, {<empty>}, type=roaring)" كل كيان يحتوي على قيمة حقل غير NULL، وهو المكمل الدقيق، والذي قد يكون مجموعة كبيرة حسب التصميم. not membership_matchهو المكمل الدقيق لمجموعة الأعضاء على الكيانات التي تحتوي على قيم حقول غير NULL، وليس تقريبًا.
في المقاطع المختومة التي يتم تحميلها على أساس الفهرس فقط، دون بيانات سكالارية خام، يستخدم التقييم بحثًا عكسيًا محدودًا عندما يدعم الفهرس ذلك. وعندما لا تتوفر بيانات الحقول الخام ولا الفهرس المؤهل، يفشل الطلب باستخدام " FieldNotLoaded " بدلاً من إرجاع الكيانات غير المفلترة.
القيود التشغيلية
| الإعداد | الافتراضي | قابل للتكوين | ما الذي يحدّه |
|---|---|---|---|
proxy.maxMembershipFilterSize | 64 ميغابايت | milvus.yaml الوكيل | نص واحد من نوع blob |
proxy.maxMembershipFilterPlanSize | 128 ميغابايت | milvus.yaml الوكيل | المجموع لكل طلب |
proxy.grpc.serverMaxRecvSize | 128 ميغابايت | milvus.yaml الوكيل | الطلب بأكمله |
| الحد الأقصى لعدد الحاويات المرتفع | 262,144 | ثابت في الكود | لكل مرشح |
| تقدير الذاكرة المفككة في Roaring | 64 ميغابايت | ثابت في الكود | لكل مرشح |
| حد تنسيق MBF1 | 128 ميغابايت | ثابت في الكود | الحد الأقصى لتنسيق blob |
بلوم fpr | 0.005 | منشئ العميل | هدف الإيجابية الكاذبة |
إعدادات " proxy.* " هي إعدادات خادم Milvus: يتم تعيينها بواسطة مشغل المجموعة في milvus.yaml ضمن قسم " proxy " ولا يمكن تعديلها لكل طلب أو لكل تعبير في وقت التصفية. يتم تحديد معدل القبول Roaring وسقف تنسيق MBF1 في التنفيذ ولا يمكن تكوينهما في أي مكان. يُعد صف " fpr " هو عنصر التحكم الوحيد من جانب العميل: يتم اختياره عند إنشاء الكتلة، مع نطاق مقبول يتراوح من 0.0001 إلى 0.05.
يستوعب نص الكتلة كحد أقصى حوالي 48.6 مليون عضو من نوع INT64 عند معدل fpr الافتراضي، مع السماح برأس مغلف ثابت بحجم 32 بايت في الأعلى. تغطي الميزانية على مستوى الطلب الحجم التسلسلي الإجمالي للخطط التي تحتوي على عناصر العضوية بالإضافة إلى الحجم التقديري الإجمالي بعد فك التشفير لمرشحات Roaring، وتشترك فيها الطلبات الفرعية لـ HybridSearch ومرشحات التقييم. تكون أجسام بلوم قوى اثنين: فعدد العناصر الذي يتجاوز حدود المستوى بقليل يضاعف حجم الكتلة، وغالبًا ما يتناسب معدل fpr الأعلى قليلاً مع المستوى الأدنى التالي. عندما يرفض الوكيل كتلة بلوم كبيرة الحجم، يقترح الخطأ قيمة « fpr » مناسبة.
- لا يتم تخزين نتائج تعبير العضوية مؤقتًا عبر الطلبات.
- تفشل المجموعات ذات الإصدارات المختلطة في الإغلاق: ترفض عقد الاستعلام (QueryNodes) التي تعمل برمز قديم الخطط التي تحتوي على عقد خطة العضوية. قم بترقية الوكلاء أولاً، ثم أكمل الترقية التدريجية قبل تمكين المشغل.
- تقوم سجلات الخادم بحجب بايتات الكتلة. يحتوي نص التعبير على اسم القالب فقط؛ ويتم إرسال الحمولة الثنائية خارج النطاق في قيم القالب.