تهئية بيانات Chroma ذات الثبوتية

import { ChromaClient } from 'chromadb'

تهئية العميل

const client = new ChromaClient();

عمليات العميل الشائعة

await client.reset() // مسح قاعدة البيانات

العمل مع المجموعات

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

إنشاء وعرض وحذف المجموعات

يستخدم Chroma اسم المجموعة في عنوان URL، لذلك هناك بعض القيود في التسمية:

  • يجب أن يكون طول الاسم بين 3 و 63 حرفًا.
  • يجب أن يبدأ وينتهي الاسم بأحرف صغيرة أو أرقام، ويمكن أن يحتوي على نقاط وشرطات وشرطات سفلية بينها.
  • لا يمكن أن يحتوي الاسم على نقطتين متتاليتين.
  • لا يمكن أن يكون الاسم عنوان IP صالحًا.

لإنشاء مجموعة، يجب تحديد اسم المجموعة ووظيفة حسابية للناقل اختيارية (المعروفة أيضًا باسم وظيفة التضمين). إذا تم توفير وظيفة الضمام، يجب توفيرها في كل مرة يتم فيها الوصول إلى المجموعة.

ملاحظة: تُستخدم وظيفة الضمام لحساب نواقص النص.

import { ChromaClient } from 'chromadb'

قم بإنشاء وإشارة إلى مجموعة كما هو مبين أدناه:

let collection = await client.createCollection({name: "my_collection", embeddingFunction: emb_fn})

let collection2 = await client.getCollection({name: "my_collection", embeddingFunction: emb_fn})

تأخذ وظيفة الضمام النص كمدخل وتُرجع بيانات ناقل محسوبة.

ملاحظة: يمكن للمبتدئين تعلم نماذج الضمام النصي من هذا البرنامج التعليمي.

يمكن الرجوع إلى المجموعات الحالية باستخدام .getCollection حسب الاسم، ويمكن أيضًا حذفها باستخدام .deleteCollection.

const collection = await client.getCollection({name: "tizi365"}) // الإشارة إلى المجموعة tizi365
await client.deleteCollection({name: "my_collection"}) // حذف المجموعة

وظائف المجموعة الشائعة

await collection.peek() // يُرجع أول 10 سجلات بيانات في المجموعة
await collection.count() // يرجع العدد الكلي لسجلات البيانات في المجموعة

ضبط طرق حساب المسافة لناقل الناقص

يشمل createCollection أيضًا معلمة metadata اختيارية، حيث يمكن تعيين قيمة hnsw:space لتخصيص طريقة حساب المسافة لمساحة الناقل.

ملاحظة: تُمثل بيانات الناقل التشابه بين النواقص من خلال حساب المسافة المكانية بينها، حيث تشير المسافات الأقرب إلى التشابه الأعلى والعكس صحيح.

let collection = client.createCollection("collection_name", undefined, metadata={ "hnsw:space": "cosine" })

خيارات hnsw:space الصحيحة هي "l2" أو "ip" أو "cosine". الافتراضي هو "l2".

إضافة البيانات إلى مجموعة البيانات

استخدم .add لإضافة البيانات إلى مجموعة Chroma.

أضف البيانات مباشرة دون تحديد متجهات المستند:

await collection.add({
    ids: ["id1", "id2", "id3", ...],
    metadatas: [{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...],
    documents: ["لوريم إيبسوم...", "doc2", "doc3", ...],
})
// شرح الباراميتر
// ids - مطلوب
// embeddings - اختياري
// metadata - اختياري
// documents - اختياري

إذا تلقى Chroma قائمة من المستندات، سوف يستخدم تلقائيًا وظيفة تضمين المجموعة لحساب متجهات للمستندين (إذا لم يتم توفير وظيفة تضمين عند إنشاء المجموعة، سيتم استخدام القيمة الافتراضية). سوف يخزن Chroma أيضًا المستندات بأنفسها. إذا كان المستند كبيرًا جدًا ليُستخدم مع وظيفة التضمين المحددة، ستحدث استثناء.

يجب أن تحتوي كل مستند على معرف فريد (ids). إضافة نفس المعرف مرتين سيؤدي إلى حفظ القيمة الأولية فقط. يمكن توفير قائمة اختيارية من القواميس للفهرسة (metadatas) لكل مستند لتخزين معلومات إضافية لعمليات تصفية البيانات أثناء الاستعلام.

بالإضافة إلى ذلك، يمكنك تقديم مباشرة قائمة من بيانات المتجهات المتعلقة بالمستندات، وسوف يستخدم Chroma البيانات المتجهية التي تقدمها دون حساب المتجه تلقائيًا.

await collection.add({
    ids: ["id1", "id2", "id3", ...],
    embeddings: [[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...],
    metadatas: [{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...],
    documents: ["لوريم إيبسوم...", "doc2", "doc3", ...],
})

إذا لم تتطابق أبعاد البيانات المتجهية المقدمة (الطول) مع أبعاد المجموعة، ستحدث استثناء.

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

await collection.add({
    ids: ["id1", "id2", "id3", ...],
    embeddings: [[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...],
    metadatas: [{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...],
})

ملاحظة: الوظيفة الأساسية لقاعدة البيانات المتجهية هي البحث عن الشبه الدلالي استنادًا إلى بيانات المتجه. لتقليل حجم قاعدة البيانات المتجهية وتحسين الكفاءة، يمكننا اختيار تخزين بيانات المتجه وبعض ظروف السمات التي يمكن تصفيتها في قاعدة البيانات المتجهية. يمكن تخزين البيانات الأخرى، مثل محتوى المقالة، في قواعد بيانات مثل MYSQL، طالما تم ربطها من خلال المعرفات.

استعلام بيانات المجموعة

يمكن استخدام الطريقة .query للاستعلام عن مجموعة Chroma بطرق متعددة.

يمكنك الاستعلام باستخدام مجموعة من query_embeddings (بيانات الناقل).

نصيحة: للحصول على query_embeddings، في سيناريوهات التطوير الفعلية، غالبًا ما يتم حساب استعلام المستخدم أولاً إلى ناقل الاستعلام من خلال نموذج تضمين النص، ثم يتم استخدام هذا الناقل للاستعلام عن محتوى مماثل.

const result = await collection.query({
    queryEmbeddings: [[11.1, 12.1, 13.1],[1.1, 2.3, 3.2], ...],
    nResults: 10,
    where: {"metadata_field": "is_equal_to_this"},
})
// ترتيب الإدخال
// query_embeddings - اختياري
// n_results - مطلوب
// where - اختياري
// query_texts - اختياري

سيقوم الاستعلام بإرجاع أفضل n_results نتائج لكل ناقل استعلام (query_embedding) بالترتيب. يمكن توفير قاموس تصفية where اختياري لتصفية النتائج بناءً على البيانات الوصفية المرتبطة بكل وثيقة. بالإضافة إلى ذلك، يمكن توفير قاموس تصفية where_document اختياري لتصفية النتائج بناءً على محتوى الوثيقة.

إذا لم تكن query_embeddings المقدمة متسقة مع أبعاد المجموعة، سيحدث استثناء. لضمان اتساق الناقل، يُوصى باستخدام نفس نموذج تضمين النص لحساب النواقل.

يمكنك أيضًا الاستعلام باستخدام مجموعة من النصوص الاستعلامية. ستحسب Chroma أولاً الناقل لكل نص استعلام باستخدام وظيفة التضمين للمجموعة، ثم تنفذ الاستعلام باستخدام النواقل النصية الناتجة.

await collection.query({
    nResults: 10, // n_results
    where: {"metadata_field": "is_equal_to_this"}, // where
    queryTexts: ["doc10", "thus spake zarathustra", ...], // query_text
})

يمكنك أيضًا استخدام .get للاستعلام عن البيانات من المجموعة حسب الهوية.

await collection.get({
    ids: ["id1", "id2", "id3", ...], //ids
    where: {"style": "style1"} // where
})

يدعم .get أيضًا تصفية where و where_document. إذا لم يتم توفير id، فسيُرجع جميع البيانات في المجموعة التي تطابق تصفية where و where_document.

تحديد الحقول المُرجعة

عند استخدام get أو query، يمكنك استخدام المعلمة include لتحديد حقول البيانات المرادة للعودة، بما في ذلك بيانات الناقل والوثائق وأي بيانات في البيانات الوصفية. بشكل افتراضي، يُرجع Chroma الوثائق والبيانات الوصفية ومسافات النواقل. يمكنك تحديد الحقول المرادة بالمرور بمصفوفة من أسماء الحقول إلى المعلمة تضمن لـ get أو query.

collection.get(
    include=["documents"]
)

collection.query(
    query_embeddings=[[11.1, 12.1, 13.1],[1.1, 2.3, 3.2], ...],
    include=["documents"]
)

استخدام تصفيات Where

يدعم Chroma تصفية الاستعلامات بناءً على البيانات الوصفية ومحتوى الوثيقة. يُستخدم تصفية where لتصفية البيانات الوصفية، ويُستخدم تصفية where_document لتصفية محتوى الوثيقة. فيما يلي شرح كيفية كتابة تعابير شروط التصفية.

تصفية بواسطة البيانات الوصفية

لتصفية البيانات الوصفية، يجب توفير قاموس تصفية where للاستعلام. يجب أن يكون لدى القاموس الهيكل التالي:

{
    "metadata_field": {
        <المُشغل>: <القيمة>
    }
}

تدعم تصفية البيانات الوصفية المُشغلات التالية:

  • $eq - يساوي (سلسلة نصية، عدد صحيح، عدد عشري)
  • $ne - لا يساوي (سلسلة نصية، عدد صحيح، عدد عشري)
  • $gt - أكبر من (عدد صحيح، عدد عشري)
  • $gte - أكبر من أو يساوي (عدد صحيح، عدد عشري)
  • $lt - أقل من (عدد صحيح، عدد عشري)
  • $lte - أقل من أو يساوي (عدد صحيح، عدد عشري)

استخدام المُشغل $eq يعادل استخدام تصفية where.

{
    "metadata_field": "search_string"
}


{
    "metadata_field": {
        "$eq": "search_string"
    }
}

تصفية محتوى الوثيقة

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

{
    "$contains": "search_string"
}

استخدام العوامل المنطقية

يمكنك أيضًا استخدام العوامل المنطقية $and و $or لدمج عدة فلاتر معًا.

يقوم عامل $and بإرجاع النتائج التي تطابق كل الفلاتر في القائمة.

{
    "$and": [
        {
            "اسم_الميتاداتا": {
                <العامل>: <القيمة>
            }
        },
        {
            "اسم_الميتاداتا": {
                <العامل>: <القيمة>
            }
        }
    ]
}

يقوم عامل $or بإرجاع النتائج التي تطابق أي شرط فلتر في القائمة.

{
    "$or": [
        {
            "اسم_الميتاداتا": {
                <العامل>: <القيمة>
            }
        },
        {
            "اسم_الميتاداتا": {
                <العامل>: <القيمة>
            }
        }
    ]
}

تحديث البيانات

تدعم Chroma أيضًا عملية الإدراج والتحديث upsert، التي يمكن أن تقوم بتحديث البيانات الحالية وإدراج بيانات جديدة إذا لم تكن البيانات موجودة.

await collection.upsert({
    ids: ["id1", "id2", "id3"],
    embeddings: [[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2]],
    metadatas: [{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}],
    documents: ["doc1", "doc2", "doc3"]
})

حذف البيانات

تدعم Chroma استخدام .delete لحذف البيانات من المجموعة حسب الهوية.

await collection.delete({
    ids: ["id1", "id2", "id3",...], // الهويات
    where: {"chapter": "20"} // الشرط
})