تصفية
مع Qdrant ، يمكنك تعيين شروط للبحث أو استرداد النقاط، مما يعني أنه يمكنك التصفية حسب السمات بالإضافة إلى عمليات البحث عن الشبه للقواعد، وهذا يشبه تعيين شروط where
في SQL. على سبيل المثال، يمكنك تعيين شروط للحمولة و id
للنقطة.
من المهم تعيين شروط إضافية عند عدم إمكانية التعبير عن كل ميزات كائن في التضمين. على سبيل المثال، متطلبات الأعمال المختلفة مثل توافر المخزون، موقع المستخدم، أو نطاق الأسعار المتوقع.
شروط التصفية
Qdrant تسمح لك بدمج الشروط في عبارات. العبارات هي عمليات منطقية مختلفة، مثل OR
، AND
، و NOT
. يمكن تضمين العبارات داخل بعضها بشكل متكرر، بحيث يمكنك إعادة إنشاء أي تعبير منطقي.
لنلقي نظرة على العبارات المطبقة في Qdrant.
لنفترض أن لدينا مجموعة من النقاط مع حمولات:
[
{ "id": 1, "city": "London", "color": "green" },
{ "id": 2, "city": "London", "color": "red" },
{ "id": 3, "city": "London", "color": "blue" },
{ "id": 4, "city": "Berlin", "color": "red" },
{ "id": 5, "city": "Moscow", "color": "green" },
{ "id": 6, "city": "Moscow", "color": "blue" }
]
يجب
مثال:
POST /collections/{collection_name}/points/scroll
{
"filter": {
"must": [
{ "key": "city", "match": { "value": "London" } },
{ "key": "color", "match": { "value": "red" } }
]
}
...
}
ستكون النقاط المصفاة:
[{ "id": 2, "city": "London", "color": "red" }]
عند استخدام must
، تكون العبارة true
فقط إذا تم تحقيق كل شرط مدرج في must
. في هذا السياق، يكون must
مكافئًا لعامل AND
.
ينبغي
Should
مشابه لعامل OR
في SQL.
مثال:
POST /collections/{collection_name}/points/scroll
{
"filter": {
"should": [
{ "key": "city", "match": { "value": "London" } },
{ "key": "color", "match": { "value": "red" } }
]
}
...
}
ستكون النقاط المصفاة:
[
{ "id": 1, "city": "London", "color": "green" },
{ "id": 2, "city": "London", "color": "red" },
{ "id": 3, "city": "London", "color": "blue" },
{ "id": 4, "city": "Berlin", "color": "red" }
]
عند استخدام should
، تكون العبارة true
طالما تم تحقيق شرط واحد على الأقل مدرج في should
. في هذا السياق، يكون should
مكافئًا لعامل OR
.
يجب_لا
مثال:
POST /collections/{collection_name}/points/scroll
{
"filter": {
"must_not": [
{ "key": "city", "match": { "value": "London" } },
{ "key": "color", "match": { "value": "red" } }
]
}
...
}
ستكون النقاط المصفاة:
[
{ "id": 5, "city": "Moscow", "color": "green" },
{ "id": 6, "city": "Moscow", "color": "blue" }
]
عند استخدام must_not
، تكون العبارة الفرعية true
فقط إذا لم يتم تحقيق أي من الشروط المدرجة في must_not
. في هذا السياق، يكون must_not
مكافئًا للتعبير (NOT A) AND (NOT B) AND (NOT C)
.
مزيج الشروط
يمكن استخدام العديد من الشروط معًا في نفس الوقت:
POST /collections/{collection_name}/points/scroll
{
"filter": {
"must": [
{ "key": "city", "match": { "value": "لندن" } }
],
"must_not": [
{ "key": "color", "match": { "value": "أحمر" } }
]
}
...
}
النقاط المرشّحة ستكون:
[
{ "id": 1, "city": "لندن", "color": "أخضر" },
{ "id": 3, "city": "لندن", "color": "أزرق" }
]
في هذه الحالة، يتم دمج الشروط باستخدام AND
.
بالإضافة إلى ذلك، يمكن تضمين الشروط تضمينًا متكررًا. على سبيل المثال:
POST /collections/{collection_name}/points/scroll
{
"filter": {
"must_not": [
{
"must": [
{ "key": "city", "match": { "value": "لندن" } },
{ "key": "color", "match": { "value": "أحمر" } }
]
}
]
}
...
}
النقاط المرشّحة ستكون:
[
{ "id": 1, "city": "لندن", "color": "أخضر" },
{ "id": 3, "city": "لندن", "color": "أزرق" },
{ "id": 4, "city": "برلين", "color": "أحمر" },
{ "id": 5, "city": "موسكو", "color": "أخضر" },
{ "id": 6, "city": "موسكو", "color": "أزرق" }
]
تصفية الشروط
في الحمولة، تتوافق أنواع القيم المختلفة مع أنواع مختلفة من الاستعلامات التي يمكن تطبيقها عليها. دعونا نلقِ نظرة على الحالات المتغايرة الموجودة وأنواع البيانات التي تنطبق عليها.
المطابقة
{
"key": "color",
"match": {
"value": "أحمر"
}
}
بالنسبة للأنواع الأخرى، تبدو الشروط المطابقة بنفس الشكل، ولكن مع استخدام أنواع مختلفة:
{
"key": "count",
"match": {
"value": 0
}
}
يُحقق الشرط الأبسط ما إذا كانت القيمة المخزنة مساوية للقيمة المعطاة. إذا تم تخزين قيم متعددة، يجب أن تحقق على الأقل واحدة منها الشرط. يمكن تطبيق ذلك على الكلمات الرئيسية والأعداد الصحيحة وحمولات المنطق.
أيّ مطابقة
متوفرة منذ الإصدار v1.1.0
إذا أردت التحقق مما إذا كانت القيمة المخزنة واحدة من عدة قيم، يمكنك استخدام شرط أيّ المطابقة. يعامل شرط أيّ المطابقة القيمة المعطاة كعملية OR منطقية. يمكن أيضًا وصفه بعامل IN
.
يمكنك تطبيقه على الكلمات الرئيسية والأعداد الصحيحة.
على سبيل المثال:
{
"key": "color",
"match": {
"any": ["أسود", "أصفر"]
}
}
في هذا المثال، إذا كانت القيمة المخزنة هي أسود
أو أصفر
، سيتم تحقيق الشرط.
إذا كانت القيمة المخزنة مصفوفة، يجب أن تحتوي على ما لا يقل عن قيمة واحدة تتطابق مع أيّ من القيم المعطاة. على سبيل المثال، إذا كانت القيمة المخزنة هي ["أسود", "أخضر"]
، سيتم تحقيق الشرط لأن "أسود"
موجود في ["أسود", "أصفر"]
.
استثناء المطابقة
متوفرة منذ الإصدار v1.2.0
إذا أردت التحقق مما إذا كانت القيمة المخزنة ليست أيّ مما يأتي من عدة قيم، يمكنك استخدام شرط استثناء المطابقة. يعامل شرط استثناء المطابقة القيمة المعطاة كعملية NOR منطقية. يمكن أيضًا وصفه بعامل NOT IN
.
يمكنك تطبيقه على الكلمات الرئيسية والأعداد الصحيحة.
على سبيل المثال:
{
"key": "color",
"match": {
"except": ["أسود", "أصفر"]
}
}
في هذا المثال، إذا كانت القيمة المخزنة ليست "أسود"
ولا "أصفر"
، سيتم تحقيق الشرط.
إذا كانت القيمة المخزنة مصفوفة، يجب أن تحتوي على ما لا يقل عن قيمة واحدة لا تتطابق مع أيّ من القيم المعطاة. على سبيل المثال، إذا كانت القيمة المخزنة هي ["أسود", "أخضر"]
، سيتم تحقيق الشرط لأن "أخضر"
لا يتطابق مع "أسود"
أو "أصفر"
.
المفاتيح المتداخلة
متاحة من الإصدار v1.1.0 فصاعدًا
نظرًا لأن الحمولة هي كائن JSON تخضع للتقدير، قد تحتاج إلى تصفية الحقول المتداخلة.
للراحة، نحن نستخدم بنية بناء مشابهة لمشروع Jq.
لنفترض أن لدينا مجموعة نقاط تحتوي على الحمولة التالية:
[
{
"id": 1,
"country": {
"name": "Germany",
"cities": [
{
"name": "Berlin",
"population": 3.7,
"sightseeing": ["Brandenburg Gate", "Reichstag"]
},
{
"name": "Munich",
"population": 1.5,
"sightseeing": ["Marienplatz", "Olympiapark"]
}
]
}
},
{
"id": 2,
"country": {
"name": "Japan",
"cities": [
{
"name": "Tokyo",
"population": 9.3,
"sightseeing": ["Tokyo Tower", "Tokyo Skytree"]
},
{
"name": "Osaka",
"population": 2.7,
"sightseeing": ["Osaka Castle", "Universal Studios Japan"]
}
]
}
}
]
يمكنك استخدام تعبيرات النقط للبحث في الحقول المتداخلة.
POST /collections/{collection_name}/points/scroll
{
"filter": {
"should": [
{
"key": "country.name",
"match": {
"value": "Germany"
}
}
]
}
}
يمكنك أيضًا استخدام بنية [ ]
للبحث في المصفوفة عن طريق إظهار القيم الداخلية.
POST /collections/{collection_name}/points/scroll
{
"filter": {
"should": [
{
"key": "country.cities[].population",
"range": {
"gte": 9.0,
}
}
]
}
}
يخرج هذا الاستعلام فقط النقطة ذات الهوية 2، حيث أن اليابان فقط لديها مدينة يبلغ تعداد سكانها أكثر من 9.0.
يمكن أيضًا أن تكون الحقول المتداخلة مصفوفة.
POST /collections/{collection_name}/points/scroll
{
"filter": {
"should": [
{
"key": "country.cities[].sightseeing",
"match": {
"value": "Osaka Castle"
}
}
]
}
}
يخرج هذا الاستعلام فقط النقطة ذات الهوية 2، حيث أن اليابان فقط لديها مدينة تحتوي على موقع سياحي يتضمن "قلعة أوساكا".
تصفية الكائنات المتداخلة
متوفرة منذ الإصدار 1.2.0
بشكل افتراضي، تأخذ الشروط في الاعتبار حمولة النقطة بأكملها.
على سبيل المثال، بناءً على النقطتين في الحمولة أدناه:
[
{
"id": 1,
"dinosaur": "t-rex",
"diet": [
{ "food": "leaves", "likes": false},
{ "food": "meat", "likes": true}
]
},
{
"id": 2,
"dinosaur": "diplodocus",
"diet": [
{ "food": "leaves", "likes": true},
{ "food": "meat", "likes": false}
]
}
]
ستطابق الاستعلام التالي هاتين النقطتين:
POST /collections/{collection_name}/points/scroll
{
"filter": {
"must": [
{
"key": "diet[].food",
"match": {
"value": "meat"
}
},
{
"key": "diet[].likes",
"match": {
"value": true
}
}
]
}
}
السبب في تطابق النقطتين أعلاه يعود إلى أن كلاهما يرضي هذين الشرطين:
- "t-rex" يرضي
diet[1].food
بـ food = meat وdiet[1].likes
بـ likes = true - "diplodocus" يرضي
diet[1].food
بـ food = meat وdiet[0].likes
بـ likes = true
للحصول فقط على النقاط التي تطابق الشروط لعناصر المصفوفة، على سبيل المثال، النقطة ذات الرقم المعرف 1 في هذا المثال، يجب استخدام تصفيات الكائنات المتداخلة.
تسمح تصفيات الكائنات المتداخلة باستعلام مصفوفات الكائنات بشكل مستقل.
يمكن تحقيق ذلك عن طريق استخدام نوع الشرط nested
، الذي يتكون من مفتاح الحمولة المهم والفلتر الذي ينبغي تطبيقه.
يجب أن يشير المفتاح إلى مصفوفة كائن ويمكن استخدام النقاط العلوية اختياريًا ("data" أو "data[]").
POST /collections/{collection_name}/points/scroll
{
"filter": {
"must": [
"nested": {
{
"key": "diet",
"filter": {
"must": [
{
"key": "food",
"match": {
"value": "meat"
}
},
{
"key": "likes",
"match": {
"value": true
}
}
]
}
}
}
]
}
}
تم تعديل منطق التوافق لتطبيقه على مستوى عنصر المصفوفة داخل الحمولة.
يعمل الفلتر المتداخل بنفس الطريقة كعند تطبيق فلتر متداخل على عنصر واحد من مصفوفة. طالما أن عنصر واحد على الأقل من المصفوفة يتوافق مع الفلتر المتداخل، يُعتبر الوثيقة الأصلية متوافقة مع الشرط.
القيود
لا تدعم تصفيات الكائنات المتداخلة شرط has_id
. إذا كنت بحاجة لاستخدامه، ضعه في بند مساوٍ must
مجاور.
POST /collections/{collection_name}/points/scroll
{
"filter": {
"must": [
"nested": {
{
"key": "diet",
"filter": {
"must": [
{
"key": "food",
"match": {
"value": "meat"
}
},
{
"key": "likes",
"match": {
"value": true
}
}
]
}
}
},
{ "has_id": [1] }
]
}
}
توافق النصوص الدقيقة
متوفرة منذ الإصدار 0.10.0
حالة خاصة من شرط التطابق "match" هو شرط التطابق بالنصوص "text". يُتيح لك البحث عن مقاطع فرعية محددة أو رموز أو عبارات معينة داخل حقل النص.
النصوص الدقيقة التي تستوفي هذا الشرط تعتمد على تكوين الفهرس النصي الكامل. يتم تحديد التكوين عند إنشاء الفهرس ويوصف ضمن الفهرس النصي الكامل.
إذا لم يكن للحقل فهرس نصي كامل، سيعمل هذا الشرط استنادًا إلى التطابق الدقيق لمقاطع النص.
{
"key": "description",
"match": {
"text": "جيدة ورخيصة"
}
}
إذا كان للاستعلام عدة كلمات، فإن هذا الشرط سيكون قد تم تحقيقه فقط عندما تظهر جميع الكلمات في النص.
النطاق
{
"key": "price",
"range": {
"gt": null,
"gte": 100.0,
"lt": null,
"lte": 450.0
}
}
شرط "range" يحدد النطاق المحتمل للقيم للحمولة المخزنة. إذا تم تخزين قيم متعددة، يجب أن تتطابق قيمة واحدة على الأقل مع الشرط.
تشمل العمليات المقارنة المتاحة:
-
gt
- أكبر من -
gte
- أكبر من أو يساوي -
lt
- أقل من -
lte
- أقل من أو يساوي
يمكن تطبيقها على الأرقام عشرية وحمولة الأعداد الصحيحة.
مربع الحدود الجغرافية
{
"key": "location",
"geo_bounding_box": {
"bottom_right": {
"lat": 52.495862,
"lon": 13.455868
},
"top_left": {
"lat": 52.520711,
"lon": 13.403683
}
}
}
يتطابق مع "location" داخل المستطيل بإحداثيات في الجهة السفلية اليمنى كـ "bottom_right" وإحداثيات في الجهة العلوية اليسرى كـ "top_left".
نصف قطر جغرافي
{
"key": "location",
"geo_radius": {
"center": {
"lat": 52.520711,
"lon": 13.403683
},
"radius": 1000.0
}
}
يتطابق مع "location" داخل الدائرة مع الوسط في "center" ونصف قطر "radius" بوحدة قياس "متر".
إذا تم تخزين قيم متعددة، يجب أن تتطابق قيمة واحدة على الأقل مع الشرط. يمكن تطبيق هذه الشروط فقط على الحمولات التي تتطابق مع تنسيق البيانات الجغرافية.
عدد القيم
بالإضافة إلى المقارنة المباشرة للقيم، يمكن أن يكون التصفية أيضًا استنادًا إلى عدد القيم.
على سبيل المثال، بالنظر إلى البيانات التالية:
[
{ "id": 1, "name": "منتج أ", "comments": ["رائع جدًا!", "ممتاز"] },
{ "id": 2, "name": "منتج ب", "comments": ["مقبول", "متوقع المزيد", "جيد"] }
]
يمكننا البحث فقط عن العناصر ذات أكثر من تعليقين:
{
"key": "comments",
"values_count": {
"gt": 2
}
}
سيكون النتيجة:
[{ "id": 2, "name": "منتج ب", "comments": ["مقبول", "متوقع المزيد", "جيد"] }]
إذا كانت القيمة المخزنة ليست مصفوفة، يُفترض أن عدد القيم يساوي 1.
فارغ
أحيانًا، من المفيد تصفية السجلات التي تفتقر إلى قيم معينة. يمكن أن يساعد شرط "IsEmpty" في تحقيق ذلك:
{
"is_empty": {
"key": "reports"
}
}
سيتم تطابق هذا الشرط مع جميع السجلات التي لا تحتوي حقل "reports" أو لديها قيمة "null" أو "[]".
IsEmpty غالبًا ما يكون مفيدًا للغاية عند استخدامه بالتزامن مع النفي المنطقي must_not. في هذه الحالة، سيتم تحديد جميع القيم الغير فارغة.
فارغة
لا يمكن للشرط match اختبار قيم "NULL". علينا استخدام شرط IsNull
:
{
"is_null": {
"key": "reports"
}
}
سيتم تطابق هذا الشرط مع جميع السجلات التي يحتوي حقل "reports" على قيمة "NULL".
لديها معرّف
هذا النوع من الاستعلامات غير متعلق بالحمولات، ولكنه مفيد جدًا في بعض الحالات. على سبيل المثال، قد يرغب المستخدمون في وسم نتائج البحث المعيّنة بأنها غير ذات صلة، أو قد نرغب فقط في البحث بين نقاط معيّنة.
POST /collections/{collection_name}/points/scroll
{
"filter": {
"must": [
{ "has_id": [1,3,5,7,9,11] }
]
}
...
}
سيكون النقاط المصفاة على النحو التالي:
[
{ "id": 1, "city": "لندن", "color": "أخضر" },
{ "id": 3, "city": "لندن", "color": "أزرق" },
{ "id": 5, "city": "موسكو", "color": "أخضر" }
]