استعلامات Elasticsearch إلى ميلفوس

يعد Elasticsearch، المبني على Apache Lucene، محرك بحث رائد مفتوح المصدر. ومع ذلك، فإنه يواجه تحديات في تطبيقات الذكاء الاصطناعي الحديثة، بما في ذلك ارتفاع تكاليف التحديث، وضعف الأداء في الوقت الحقيقي، وإدارة القطع غير الفعالة، والتصميم غير السحابي الأصلي، والمتطلبات المفرطة للموارد. وباعتبارها قاعدة بيانات متجهة سحابية أصلية، تتغلب Milvus على هذه المشكلات من خلال التخزين والحوسبة المنفصلين، والفهرسة الفعالة للبيانات عالية الأبعاد، والتكامل السلس مع البنى التحتية الحديثة. يوفر أداءً فائقًا وقابلية توسع فائقة لأعباء عمل الذكاء الاصطناعي.

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

نظرة عامة

في Elasticsearch، تُنشئ العمليات في سياق الاستعلام درجات الملاءمة، بينما لا تُنشئ العمليات في سياق التصفية. وبالمثل، تنتج عمليات البحث في Milvus درجات تشابه، في حين أن الاستعلامات الشبيهة بالفلتر لا تنتج درجات تشابه. عند ترحيل قاعدة التعليمات البرمجية الخاصة بك من Elasticsearch إلى Milvus، فإن المبدأ الأساسي هو تحويل الحقول المستخدمة في سياق استعلام Elasticsearch إلى حقول متجهة لتمكين توليد درجات التشابه.

يوجز الجدول أدناه بعض أنماط استعلامات Elasticsearch ومكافئاتها المقابلة في Milvus.

استعلامات Elasticsearch

معادلات ميلفوس

الملاحظات

استعلامات النص الكامل

استعلام مطابقة

بحث النص الكامل

كلاهما يوفران مجموعات متشابهة من الإمكانيات.

استعلامات على مستوى المصطلح

المعرفات

in المشغل

كلاهما يوفران نفس مجموعة الإمكانيات أو مجموعة مماثلة من الإمكانيات عند استخدام استعلامات Elasticsearch هذه في سياق التصفية.

استعلام البادئة

like المشغّل

استعلام النطاق

مشغلات المقارنة مثل > ، < ، ، >= ، و <=

استعلام المدى

عوامل المقارنة مثل ==

استعلام المصطلحات

in المشغل

استعلام أحرف البدل

like مشغّل

الاستعلام المنطقي

المشغلات المنطقية مثل AND

كلاهما يوفران مجموعات متشابهة من الإمكانيات عند استخدامهما في سياق التصفية.

الاستعلامات المتجهة

استعلام kNN

بحث

يوفر ميلفوس إمكانيات بحث متجهية أكثر تقدمًا.

دمج الرتب المتبادلة

البحث الهجين

يدعم ميلفوس استراتيجيات متعددة لإعادة الترتيب.

استعلامات النص الكامل

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

استعلام المطابقة

في Elasticsearch، يقوم استعلام المطابقة بإرجاع المستندات التي تطابق نصًا أو رقمًا أو تاريخًا أو قيمة منطقية. يتم تحليل النص المُقدَّم قبل المطابقة.

فيما يلي مثال لطلب بحث في Elasticsearch مع استعلام مطابقة.

resp = client.search(
    query={
        "match": {
            "message": {
                "query": "this is a test"
            }
        }
    },
)

يوفر ميلفوس نفس الإمكانية من خلال ميزة البحث في النص الكامل. يمكنك تحويل استعلام Elasticsearch أعلاه إلى Milvus على النحو التالي:

res = client.search(
    collection_name="my_collection",
    data=['How is the weather in Jamaica?'],
    anns_field="message_sparse",
    output_fields=["id", "message"]
)

في المثال أعلاه، message_sparse هو حقل متجه متناثر مشتق من حقل VarChar اسمه message. يستخدم Milvus نموذج التضمين BM25 لتحويل القيم الموجودة في الحقل message إلى تضمينات متجهات متناثرة ويخزنها في الحقل message_sparse. عند تلقي طلب البحث، يقوم Milvus بتضمين حمولة الاستعلام النصية العادية باستخدام نفس نموذج BM25 ويقوم بإجراء بحث متجهي متناثر وإرجاع الحقلين id و message المحددين في المعلمة output_fields مع درجات التشابه المقابلة.

لاستخدام هذه الوظيفة، يجب تمكين المحلل على الحقل message وتحديد دالة لاشتقاق الحقل message_sparse منه. للحصول على إرشادات مفصلة حول تمكين المحلل وإنشاء الدالة المشتقة في ميلفوس، راجع البحث في النص الكامل.

الاستعلامات على مستوى المصطلح

في Elasticsearch، تُستخدم الاستعلامات على مستوى المصطلح للعثور على المستندات بناءً على القيم الدقيقة في البيانات المهيكلة، مثل نطاقات التواريخ أو عناوين IP أو الأسعار أو معرّفات المنتجات. يوضح هذا القسم المعادلات الممكنة لبعض استعلامات مستوى المصطلح في Elasticsearch في ميلفوس. تم تكييف جميع الأمثلة في هذا القسم لتعمل ضمن سياق التصفية لتتماشى مع إمكانيات ملفوس.

المعرفات

في Elasticsearch، يمكنك العثور على المستندات بناءً على معرّفاتها في سياق التصفية على النحو التالي:

resp = client.search(
    query={
        "bool": {
            "filter": {
                "ids": {
                    "values": [
                        "1",
                        "4",
                        "100"
                    ]
                }            
            }
        }
    },
)

في ميلفوس، يمكنك أيضًا العثور على الكيانات بناءً على معرّفاتها على النحو التالي:

# Use the filter parameter
res = client.query(
    collection_name="my_collection",
    filter="id in [1, 4, 100]",
    output_fields=["id", "title"]
)

# Use the ids parameter
res = client.query(
    collection_name="my_collection",
    ids=[1, 4, 100],
    output_fields=["id", "title"]
)

يمكنك العثور على مثال Elasticsearch في هذه الصفحة. للحصول على تفاصيل حول طلبات الاستعلام والحصول على الطلبات بالإضافة إلى تعبيرات التصفية في Milvus، راجع الاستعلام والتصفية.

استعلام البادئة

في Elasticsesearch، يمكنك العثور على المستندات التي تحتوي على بادئة محددة في حقل متوفر في سياق التصفية على النحو التالي:

resp = client.search(
    query={
        "bool": {
            "filter": {
                 "prefix": {
                    "user": {
                        "value": "ki"
                    }
                }           
            }
        }
    },
)

في ميلفوس، يمكنك العثور على الكيانات التي تبدأ قيمها بالبادئة المحددة على النحو التالي:

res = client.query(
    collection_name="my_collection",
    filter='user like "ki%"',
    output_fields=["id", "user"]
)

يمكنك العثور على مثال Elasticsearch في هذه الصفحة. للحصول على تفاصيل حول مشغل like في ميلفوس، راجع استخدام LIKE لمطابقة الأنماط.

استعلام النطاق

في Elasticsearch، يمكنك العثور على المستندات التي تحتوي على مصطلحات ضمن نطاق محدد على النحو التالي:

resp = client.search(
    query={
        "bool": {
            "filter": {
                "range": {
                    "age": {
                        "gte": 10,
                        "lte": 20
                    }
                }           
            }
        }
    },
)

في Milvus، يمكنك العثور على الكيانات التي تقع قيمها في حقل معين ضمن نطاق محدد على النحو التالي:

res = client.query(
    collection_name="my_collection",
    filter='10 <= age <= 20',
    output_fields=["id", "user", "age"]
)

يمكنك العثور على مثال Elasticsearch في هذه الصفحة. للحصول على تفاصيل حول عوامل المقارنة في ملفوس، راجع عوامل المقارنة.

استعلام المدى

في Elasticsearch، يمكنك العثور على المستندات التي تحتوي على مصطلح محدد في حقل معين على النحو التالي:

resp = client.search(
    query={
        "bool": {
            "filter": {
                "term": {
                    "status": {
                        "value": "retired"
                    }
                }            
            }
        }
    },
)

في ميلفوس، يمكنك العثور على الكيانات التي تكون قيمها في الحقل المحدد هي بالضبط المصطلح المحدد على النحو التالي:

# use ==
res = client.query(
    collection_name="my_collection",
    filter='status=="retired"',
    output_fields=["id", "user", "status"]
)

# use TEXT_MATCH
res = client.query(
    collection_name="my_collection",
    filter='TEXT_MATCH(status, "retired")',
    output_fields=["id", "user", "status"]
)

يمكنك العثور على مثال Elasticsearch في هذه الصفحة. للحصول على تفاصيل حول عوامل المقارنة في ميلفوس، راجع عوامل المقارنة.

استعلام المصطلحات

في Elasticsearch، يمكنك العثور على المستندات التي تحتوي على مصطلح واحد أو أكثر من المصطلحات الدقيقة في حقل محدد على النحو التالي:

resp = client.search(
    query={
        "bool": {
            "filter": {
                "terms": {
                    "degree": [
                        "graduate",
                        "post-graduate"
                    ]
                }        
            }
        }
    }
)

ليس لدى ميلفوس مكافئ كامل لهذا. ومع ذلك، يمكنك العثور على الكيانات التي تكون قيمها في الحقل المحدد أحد المصطلحات المحددة على النحو التالي:

# use in
res = client.query(
    collection_name="my_collection",
    filter='degree in ["graduate", "post-graduate"]',
    output_fields=["id", "user", "degree"]
)

# use TEXT_MATCH
res = client.query(
    collection_name="my_collection",
    filter='TEXT_MATCH(degree, "graduate post-graduate")',
    output_fields=["id", "user", "degree"]
)

يمكنك العثور على مثال Elasticsearch في هذه الصفحة. للحصول على تفاصيل حول مشغلي النطاق في ميلفوس، راجع مشغلي النطاق.

استعلام أحرف البدل

في Elasticsearch، يمكنك العثور على المستندات التي تحتوي على مصطلحات مطابقة لنمط حرف بدل على النحو التالي:

resp = client.search(
    query={
        "bool": {
            "filter": {
                "wildcard": {
                    "user": {
                        "value": "ki*y"
                    }
                }          
            }
        }
    },
)

لا يدعم Milvus أحرف البدل في شروط التصفية الخاصة به. ومع ذلك، يمكنك استخدام المشغل like لتحقيق تأثير مماثل على النحو التالي:

res = client.query(
    collection_name="my_collection",
    filter='user like "ki%" AND user like "%y"',
    output_fields=["id", "user"]
)

يمكنك العثور على مثال Elasticsearch في هذه الصفحة. للحصول على تفاصيل حول مشغلات النطاق في ميلفوس، راجع مشغلات النطاق.

الاستعلام المنطقي

في Elasticsearch، الاستعلام المنطقي هو استعلام يطابق المستندات التي تطابق مجموعات منطقية من الاستعلامات الأخرى.

المثال التالي مقتبس من مثال في وثائق Elasticsearch في هذه الصفحة. سيعيد الاستعلام المستخدمين الذين لديهم kimchy في أسمائهم مع علامة production.

resp = client.search(
    query={
        "bool": {
            "filter": {
                "term": {
                    "user": "kimchy"
                }
            },
            "filter": {
                "term": {
                    "tags": "production"
                }
            }
        }
    },
)

في ميلفوس، يمكنك القيام بالأمر نفسه على النحو التالي:

filter = 

res = client.query(
    collection_name="my_collection",
    filter='user like "%kimchy%" AND ARRAY_CONTAINS(tags, "production")',
    output_fields=["id", "user", "age", "tags"]
)

يفترض المثال أعلاه أن لديك حقل user من نوع VarChar وحقل tags من نوع Array، في المجموعة المستهدفة. سيعيد الاستعلام المستخدمين الذين لديهم kimchy في أسمائهم بعلامة production.

الاستعلامات المتجهة

في Elasticsearch، الاستعلامات المتجهة هي استعلامات متخصصة تعمل على الحقول المتجهة لإجراء بحث دلالي بكفاءة.

استعلام كن

يدعم Elasticsearch كلاً من استعلامات kNN التقريبية واستعلامات kNN الدقيقة والغاشمة. يمكنك العثور على أقرب متجهات k إلى متجه استعلام بأي من الطريقتين، كما تقاس بمقياس تشابه، على النحو التالي:

resp = client.search(
    index="my-image-index",
    size=3,
    query={
        "knn": {
            "field": "image-vector",
            "query_vector": [
                -5,
                9,
                -12
            ],
            "k": 10
        }
    },
)

يستخدم ميلفوس، باعتباره قاعدة بيانات متجهات متخصصة، أنواع الفهارس لتحسين عمليات البحث عن المتجهات. وعادةً ما يعطي الأولوية للبحث عن أقرب جار تقريبي (ANN) لبيانات المتجهات عالية الأبعاد. على الرغم من أن البحث باستخدام القوة الغاشمة kNN باستخدام نوع الفهرس المسطح يوفر نتائج دقيقة، إلا أنه يستغرق وقتًا طويلاً ويستهلك الكثير من الموارد. في المقابل، يوازن البحث باستخدام ANN باستخدام AUTOINDEX أو أنواع الفهارس الأخرى بين السرعة والدقة، مما يوفر أداءً أسرع بكثير وأكثر كفاءة في استخدام الموارد من kNN.

هناك مكافئ مماثل للاستعلام المتجه أعلاه في Mlivus على هذا النحو:

res = client.search(
    collection_name="my_collection",
    anns_field="image-vector"
    data=[[-5, 9, -12]],
    limit=10
)

يمكنك العثور على مثال Elasticsearch في هذه الصفحة. للحصول على تفاصيل حول عمليات بحث الشبكة العصبية الاصطناعية في ميليفوس، اقرأ بحث الشبكة العصبية الاصطناعية الأساسي.

دمج الرتب المتبادلة

يوفّر Elasticsearch خاصية دمج الرتب المتبادلة (RRF) لدمج مجموعات نتائج متعددة بمؤشرات صلة مختلفة في مجموعة نتائج واحدة مرتبة.

يوضح المثال التالي الجمع بين بحث تقليدي قائم على المصطلح مع بحث متجه على أساس k-أقرب الجيران (kNN) لتحسين ملاءمة البحث:

client.search(
    index="my_index",
    size=10,
    query={
        "retriever": {
            "rrf": {
                "retrievers": [
                    {
                        "standard": {
                            "query": {
                                "term": {
                                    "text": "shoes"
                                }
                            }
                        }
                    },
                    {
                        "knn": {
                            "field": "vector",
                            "query_vector": [1.25, 2, 3.5],  # Example vector; replace with your actual query vector
                            "k": 50,
                            "num_candidates": 100
                        }
                    }
                ],
                "rank_window_size": 50,
                "rank_constant": 20
            }
        }
    }
)

في هذا المثال، يجمع RRF في هذا المثال بين نتائج من مسترجعين اثنين:

  • بحث قياسي قائم على المصطلح عن المستندات التي تحتوي على المصطلح "shoes" في الحقل text.

  • بحث kNN على الحقل vector باستخدام متجه الاستعلام المقدم.

يساهم كل مسترجع بما يصل إلى 50 من أفضل التطابقات، والتي يتم إعادة ترتيبها بواسطة RRF، ويتم إرجاع أفضل 10 نتائج نهائية.

في Milvus، يمكنك تحقيق بحث هجين مماثل من خلال الجمع بين عمليات البحث عبر حقول متجهات متعددة، وتطبيق استراتيجية إعادة الترتيب، واسترجاع أفضل النتائج من القائمة المدمجة. يدعم Milvus كلاً من استراتيجيات إعادة الترتيب الموزونة واستراتيجيات إعادة الترتيب الموزونة. لمزيد من التفاصيل، راجع إعادة الترتيب.

ما يلي هو معادلة غير صارمة لمثال Elasticsearch أعلاه في Milvus.

search_params_dense = {
    "data": [[1.25, 2, 3.5]],
    "anns_field": "vector",
    "param": {
        "metric_type": "IP",
        "params": {"nprobe": 10},
    },
    "limit": 100
}

req_dense = ANNSearchRequest(**search_params_dense)

search_params_sparse = {
    "data": ["shoes"],
    "anns_field": "text_sparse",
    "param": {
        "metric_type": "BM25",
    }
}

req_sparse = ANNSearchRequest(**search_params_sparse)

res = client.hybrid_search(
    collection_name="my_collection",
    reqs=[req_dense, req_sparse],
    reranker=RRFRanker(),
    limit=10
)

يوضح هذا المثال بحثًا هجينًا في ميلفوس يجمع بين:

  1. بحث متجه كثيف: استخدام مقياس الضرب الداخلي (IP) مع ضبط nprobe على 10 للبحث التقريبي لأقرب جار (ANN) على الحقل vector.

  2. بحث متجه متناثر: استخدام مقياس التشابه BM25 على الحقل text_sparse.

يتم تنفيذ النتائج من عمليات البحث هذه بشكل منفصل ودمجها وإعادة ترتيبها باستخدام مصنف دمج الرتب المتبادل (RRF). يُرجع البحث المختلط أفضل 10 كيانات من القائمة المعاد ترتيبها.

على عكس تصنيف RRRF الخاص بـ Elasticsearch، الذي يدمج النتائج من الاستعلامات القياسية المستندة إلى النص وعمليات البحث kNN، يجمع Milvus بين النتائج من عمليات البحث المتفرقة والكثيفة المتجهة، مما يوفر إمكانية بحث هجين فريدة من نوعها ومُحسّنة للبيانات متعددة الوسائط.

الخلاصة

في هذه المقالة، قمنا بتغطية تحويل استعلامات Elasticsearch النموذجية إلى معادلاتها في Milvus، بما في ذلك الاستعلامات على مستوى المصطلح والاستعلامات المنطقية واستعلامات النص الكامل والاستعلامات المتجهة. إذا كانت لديك أسئلة أخرى حول تحويل استعلامات Elasticsearch الأخرى، فلا تتردد في التواصل معنا.