الدرس 8 من 23

نماذج التضمين وقواعد البيانات المتجهة

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

3 دقيقة للقراءة

تصفية البيانات الوصفية تجمع الاستعلامات المهيكلة مع تشابه المتجهات، مما يمكّن استرجاع دقيق لا يمكن للبحث الدلالي النقي تحقيقه.

لماذا البيانات الوصفية مهمة

البحث الدلالي وحده له قيود:

# الاستعلام: "سياسة الإرجاع للإلكترونيات"
# المشكلة: يسترجع سياسات الإرجاع من جميع الأقسام

# مع تصفية البيانات الوصفية:
results = vectorstore.similarity_search(
    query="سياسة الإرجاع",
    k=5,
    filter={"department": "electronics"}
)
# الآن يسترجع فقط السياسات الخاصة بالإلكترونيات

تصميم مخطط البيانات الوصفية

صمم البيانات الوصفية لأنماط الاسترجاع الخاصة بك:

# مستند مع بيانات وصفية غنية
document = {
    "content": "يمكن إرجاع الإلكترونيات خلال 30 يوماً...",
    "metadata": {
        # تصنيفي - للمطابقة الدقيقة
        "department": "electronics",
        "document_type": "policy",
        "language": "ar",

        # رقمي - لاستعلامات النطاق
        "page_number": 5,
        "word_count": 250,
        "created_year": 2024,

        # منطقي - للعلامات
        "is_current": True,
        "requires_approval": False,

        # نص - للمطابقة الجزئية
        "source_file": "electronics_manual.pdf",
        "author": "أحمد محمد"
    }
}

أنماط التصفية حسب قاعدة البيانات

Pinecone

# مطابقة دقيقة
results = index.query(
    vector=query_embedding,
    top_k=5,
    filter={"department": {"$eq": "electronics"}}
)

# شروط متعددة (AND)
results = index.query(
    vector=query_embedding,
    top_k=5,
    filter={
        "$and": [
            {"department": {"$eq": "electronics"}},
            {"is_current": {"$eq": True}},
            {"created_year": {"$gte": 2023}}
        ]
    }
)

# شروط OR
results = index.query(
    vector=query_embedding,
    top_k=5,
    filter={
        "$or": [
            {"department": {"$eq": "electronics"}},
            {"department": {"$eq": "computers"}}
        ]
    }
)

# عامل IN (قيم متعددة)
results = index.query(
    vector=query_embedding,
    top_k=5,
    filter={"department": {"$in": ["electronics", "computers", "phones"]}}
)

Qdrant

from qdrant_client.models import Filter, FieldCondition, MatchValue, Range

# مطابقة دقيقة
results = client.search(
    collection_name="documents",
    query_vector=query_embedding,
    limit=5,
    query_filter=Filter(
        must=[
            FieldCondition(key="department", match=MatchValue(value="electronics"))
        ]
    )
)

# استعلام النطاق
results = client.search(
    collection_name="documents",
    query_vector=query_embedding,
    limit=5,
    query_filter=Filter(
        must=[
            FieldCondition(
                key="created_year",
                range=Range(gte=2023, lte=2024)
            )
        ]
    )
)

# شروط معقدة
results = client.search(
    collection_name="documents",
    query_vector=query_embedding,
    limit=5,
    query_filter=Filter(
        must=[
            FieldCondition(key="is_current", match=MatchValue(value=True))
        ],
        should=[  # شروط OR
            FieldCondition(key="department", match=MatchValue(value="electronics")),
            FieldCondition(key="department", match=MatchValue(value="computers"))
        ]
    )
)

Chroma

# مطابقة دقيقة
results = collection.query(
    query_embeddings=[query_embedding],
    n_results=5,
    where={"department": "electronics"}
)

# شروط متعددة (AND)
results = collection.query(
    query_embeddings=[query_embedding],
    n_results=5,
    where={
        "$and": [
            {"department": {"$eq": "electronics"}},
            {"is_current": {"$eq": True}}
        ]
    }
)

# شروط OR
results = collection.query(
    query_embeddings=[query_embedding],
    n_results=5,
    where={
        "$or": [
            {"department": {"$eq": "electronics"}},
            {"department": {"$eq": "computers"}}
        ]
    }
)

دفع المرشح مقابل التصفية اللاحقة

الاستراتيجية كيف تعمل الأداء
دفع المرشح يصفي أثناء بحث المتجهات سريع، دقيق
التصفية اللاحقة يصفي بعد استرجاع أعلى k قد يرجع < k نتيجة
# دفع المرشح (المفضل) - قاعدة البيانات تصفي أثناء البحث
results = index.query(
    vector=query_embedding,
    top_k=10,
    filter={"department": "electronics"}  # يُطبق أثناء البحث
)
# يرجع دائماً 10 نتائج تطابق المرشح

# التصفية اللاحقة (احتياطي) - تصفية بعد الاسترجاع
results = index.query(vector=query_embedding, top_k=100)
filtered = [r for r in results if r.metadata["department"] == "electronics"][:10]
# قد يرجع أقل من 10 إذا لم يكن هناك مطابقات كافية في أعلى 100

استراتيجيات مساحة الأسماء

نظم البيانات لاسترجاع فعال:

# مساحات أسماء Pinecone
index.upsert(
    vectors=[{"id": "doc1", "values": embedding, "metadata": {...}}],
    namespace="electronics"  # قسم فهرس منفصل
)

# استعلام مساحة أسماء محددة
results = index.query(
    vector=query_embedding,
    top_k=5,
    namespace="electronics"
)

# استعلام جميع مساحات الأسماء
results = index.query(
    vector=query_embedding,
    top_k=5,
    namespace=""  # سلسلة فارغة = جميع مساحات الأسماء
)

متى تستخدم مساحات الأسماء:

  • تطبيقات متعددة المستأجرين (فصل بـ tenant_id)
  • أنواع مستندات مميزة (سياسات مقابل أسئلة شائعة)
  • فصل اللغة

التصفية الديناميكية

بناء المرشحات من سياق المستخدم:

def build_filter(user_query: str, user_context: dict):
    """بناء مرشح بناءً على سياق المستخدم."""
    filters = []

    # وصول قسم المستخدم
    if user_context.get("departments"):
        filters.append({
            "department": {"$in": user_context["departments"]}
        })

    # المستندات الحالية فقط
    filters.append({"is_current": {"$eq": True}})

    # تفضيل اللغة
    if user_context.get("language"):
        filters.append({
            "language": {"$eq": user_context["language"]}
        })

    return {"$and": filters} if filters else {}

# الاستخدام
user_context = {
    "departments": ["electronics", "computers"],
    "language": "ar"
}

results = index.query(
    vector=query_embedding,
    top_k=5,
    filter=build_filter(query, user_context)
)

أفضل الممارسات

الممارسة الفائدة
فهرس حقول البيانات الوصفية تصفية أسرع
استخدم التصنيفي على النص مطابقة دقيقة
حدد تعقيد المرشح أداء الاستعلام
احسب مسبقاً المرشحات الشائعة قلل معالجة وقت التشغيل
اختبر مع بيانات واقعية تحقق من انتقائية المرشح

مبدأ التصميم: أفضل أنظمة RAG تستخدم البيانات الوصفية لتضييق مساحة البحث قبل التشابه الدلالي. فكر في المرشحات كـ "أين تبحث" والمتجهات كـ "ماذا تجد."

في الوحدة التالية، سنستكشف استراتيجيات التقطيع المتقدمة التي تؤثر مباشرة على جودة الاسترجاع. :::

اختبار

الوحدة 2: نماذج التضمين وقواعد البيانات المتجهة

خذ الاختبار