> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
تتناول هذه المواصفات المشكلات والفجوات التي تم تحديدها أثناء التنفيذ الأولي لدمج البيانات المهيكلة في TrustGraph، كما هو موضح في `structured-data.md`.
## بيان المشكلات
### 1. عدم اتساق في التسمية: "كائن" مقابل "صف"
يستخدم التنفيذ الحالي مصطلح "كائن" في جميع أنحائه (على سبيل المثال، `ExtractedObject`، واستخراج الكائنات، وتضمينات الكائنات). هذا المصطلح عام جدًا ويسبب ارتباكًا:
مصطلح "كائن" مصطلح عام ومزدحم في البرمجيات (كائنات بايثون، كائنات JSON، إلخ).
البيانات التي يتم التعامل معها هي في الأساس بيانات جدولية - صفوف في الجداول ذات المخططات المحددة.
مصطلح "صف" يصف نموذج البيانات بشكل أكثر دقة ويتوافق مع مصطلحات قواعد البيانات.
يظهر هذا التناقض في أسماء الوحدات، وأسماء الفئات، وأنواع الرسائل، والوثائق.
### 2. قيود استعلامات تخزين الصفوف
يحتوي تنفيذ تخزين الصفوف الحالي على قيود استعلام كبيرة:
**عدم تطابق مع اللغة الطبيعية**: تواجه الاستعلامات صعوبة في التعامل مع الاختلافات في البيانات الواقعية. على سبيل المثال:
من الصعب العثور على قاعدة بيانات الشوارع التي تحتوي على `"CHESTNUT ST"` عند السؤال عن `"Chestnut Street"`.
تكسر الاختصارات، والاختلافات في الأحرف الكبيرة والصغيرة، وتغيرات التنسيق استعلامات المطابقة التامة.
يتوقع المستخدمون فهمًا دلاليًا، لكن المستودع يوفر مطابقة حرفية.
**مشكلات تطور المخطط**: يؤدي تغيير المخططات إلى حدوث مشكلات:
قد لا تتوافق البيانات الموجودة مع المخططات المحدثة.
يمكن أن تؤدي تغييرات هيكل الجدول إلى تعطيل الاستعلامات وتكامل البيانات.
لا توجد مسار ترحيل واضح لتحديثات المخطط.
### 3. مطلوب تضمينات الصفوف
بالإضافة إلى المشكلة رقم 2، يحتاج النظام إلى تضمينات متجهة لبيانات الصفوف لتمكين:
البحث الدلالي عبر البيانات المهيكلة (العثور على "شارع تشيستنوت" عندما تحتوي البيانات على "CHESTNUT ST").
مطابقة التشابه للاستعلامات الغامضة.
البحث الهجين الذي يجمع بين المرشحات المهيكلة ومطابقة التشابه الدلالي.
دعم أفضل للغة الطبيعية.
تم تحديد خدمة التضمين ولكن لم يتم تنفيذها.
### 4. استيعاب بيانات الصفوف غير مكتمل
مسار استيعاب البيانات المهيكلة ليس فعالًا بالكامل:
توجد مطالبات تشخيصية لتصنيف تنسيقات الإدخال (CSV، JSON، إلخ).
خدمة الاستيعاب التي تستخدم هذه المطالبات غير متصلة بالنظام.
لا يوجد مسار شامل لتحميل البيانات المهيكلة مسبقًا إلى مستودع الصفوف.
## الأهداف
**مرونة المخطط**: تمكين تطور المخطط دون تعطل البيانات الموجودة أو الحاجة إلى عمليات ترحيل.
**تسمية متسقة**: توحيد مصطلح "صف" في جميع أنحاء قاعدة التعليمات البرمجية.
**قابلية الاستعلام الدلالي**: دعم المطابقة الغامضة / الدلالية عبر تضمينات الصفوف.
**مسار استيعاب كامل**: توفير مسار شامل لتحميل البيانات المهيكلة.
## التصميم الفني
### مخطط تخزين صفوف موحد
أنشأ التنفيذ السابق جدول Cassandra منفصل لكل مخطط. تسبب ذلك في حدوث مشكلات عند تطور المخططات، حيث تتطلب تغييرات هيكل الجدول عمليات ترحيل.
يستخدم التصميم الجديد جدولًا موحدًا واحدًا لجميع بيانات الصفوف:
`index_value = ['US', 'active']` (القيم بنفس ترتيب أسماء الحقول)
**مثال على المفتاح الأساسي:**
يحدد المخطط `customer_id` كمفتاح أساسي
`index_name = "customer_id"`
`index_value = ['CUST001']`
#### أنماط الاستعلام
تتبع جميع الاستعلامات نفس النمط بغض النظر عن الفهرس المستخدم:
```sql
SELECT * FROM rows
WHERE collection = 'import_2024'
AND schema_name = 'customers'
AND index_name = 'email'
AND index_value = ['foo@bar.com']
```
#### المقايضات التصميمية
**المزايا:**
التغييرات في المخطط لا تتطلب تغييرات في هيكل الجدول.
البيانات الموجودة في الصفوف غير مرئية لـ Cassandra - إضافة أو إزالة الحقول تكون شفافة.
نمط استعلام متسق لجميع طرق الوصول.
لا توجد فهارس ثانوية لـ Cassandra (والتي يمكن أن تكون بطيئة على نطاق واسع).
أنواع Cassandra الأصلية في جميع أنحاء النظام (`map`، `frozen<list>`).
**المقايضات:**
تضخيم الكتابة: كل إدخال صف = N إدخالات (واحد لكل حقل مفهرس).
تكلفة تخزين إضافية بسبب تكرار بيانات الصفوف.
يتم تخزين معلومات النوع في تكوين المخطط، ويتم التحويل في طبقة التطبيق.
#### نموذج الاتساق
التصميم يقبل بعض التبسيط:
1.**لا توجد تحديثات للصفوف**: النظام مخصص للإضافة فقط. هذا يلغي مخاوف الاتساق المتعلقة بتحديث نسخ متعددة من نفس الصف.
2.**تحمل تغيير المخطط**: عند تغيير المخططات (على سبيل المثال، إضافة أو إزالة الفهارس)، تحتفظ الصفوف الموجودة بفهرستها الأصلية. لن يتمكن المستخدمون من اكتشاف الصفوف القديمة عبر الفهارس الجديدة. يمكن للمستخدمين حذف وإعادة إنشاء مخطط لضمان الاتساق إذا لزم الأمر.
### تتبع الأقسام والحذف
#### المشكلة
باستخدام مفتاح التقسيم `(collection, schema_name, index_name)`، يتطلب الحذف الفعال معرفة جميع مفاتيح التقسيم المراد حذفها. يتطلب الحذف باستخدام `collection` أو `collection + schema_name` معرفة جميع قيم `index_name` التي تحتوي على بيانات.
يحتفظ كاتب الصفوف بخزن مؤقت في الذاكرة لأزواج `(collection, schema_name)` المسجلة. عند معالجة صف:
1. تحقق مما إذا كانت `(collection, schema_name)` موجودة في الذاكرة المؤقتة.
2. إذا لم تكن موجودة في الذاكرة المؤقتة (أول صف لهذه الزوج):
ابحث في تكوين المخطط للحصول على جميع أسماء الفهارس.
أدخل إدخالات في `row_partitions` لكل `(collection, schema_name, index_name)`.
أضف الزوج إلى الذاكرة المؤقتة.
3. تابع بكتابة بيانات الصف.
يراقب كاتب الصفوف أيضًا أحداث تغيير تكوين المخطط. عند حدوث تغيير في المخطط، يتم مسح إدخالات الذاكرة المؤقتة ذات الصلة بحيث يؤدي الصف التالي إلى إعادة التسجيل باستخدام أسماء الفهارس المحدثة.
يضمن هذا النهج:
تتم كتابة جداول البحث مرة واحدة لكل زوج `(collection, schema_name)`، وليس لكل صف.
يعكس جدول البحث الفهارس التي كانت نشطة عند كتابة البيانات.
يتم اكتشاف تغييرات المخطط في منتصف الاستيراد بشكل صحيح.
#### عمليات الحذف
**حذف المجموعة:**
```sql
-- 1. Discover all partitions
SELECT schema_name, index_name FROM row_partitions WHERE collection = 'X';
-- 2. Delete each partition from rows table
DELETE FROM rows WHERE collection = 'X' AND schema_name = '...' AND index_name = '...';
-- (repeat for each discovered partition)
-- 3. Clean up the lookup table
DELETE FROM row_partitions WHERE collection = 'X';
```
**حذف المجموعة والمخطط:**
```sql
-- 1. Discover partitions for this schema
SELECT index_name FROM row_partitions WHERE collection = 'X' AND schema_name = 'Y';
-- 2. Delete each partition from rows table
DELETE FROM rows WHERE collection = 'X' AND schema_name = 'Y' AND index_name = '...';
-- (repeat for each discovered partition)
-- 3. Clean up the lookup table entries
DELETE FROM row_partitions WHERE collection = 'X' AND schema_name = 'Y';
```
### تضمينات الصفوف
تتيح تضمينات الصفوف المطابقة الدلالية/التقريبية على القيم المفهرسة، مما يحل مشكلة عدم تطابق اللغة الطبيعية (على سبيل المثال، العثور على "CHESTNUT ST" عند البحث عن "Chestnut Street").
#### نظرة عامة على التصميم
يتم تضمين كل قيمة مفهرسة وتخزينها في مخزن متجه (Qdrant). في وقت الاستعلام، يتم تضمين الاستعلام، ويتم العثور على المتجهات المشابهة، ويتم استخدام البيانات الوصفية المرتبطة للبحث عن الصفوف الفعلية في Cassandra.
#### هيكل مجموعة Qdrant
مجموعة Qdrant واحدة لكل مجموعة `(user, collection, schema_name, dimension)`:
| `index_name` | الحقول المفهرسة التي يمثلها هذا التضمين. |
| `index_value` | القائمة الأصلية للقيم (للبحث في Cassandra). |
| `text` | النص الذي تم تضمينه (للتصحيح/العرض). |
ملاحظة: `user`، و `collection`، و `schema_name` مستمدة ضمنيًا من اسم مجموعة Qdrant.
#### مسار الاستعلام
1. يقوم المستخدم بالاستعلام عن "Chestnut Street" ضمن المستخدم U، والمجموعة X، والمخطط Y.
2. تضمين نص الاستعلام.
3. تحديد اسم(أسماء) مجموعة Qdrant التي تتطابق مع البادئة `rows_U_X_Y_`.
4. البحث في مجموعة(مجموعات) Qdrant المطابقة عن أقرب المتجهات.
5. الحصول على النقاط المطابقة التي تحتوي على حمولات تحتوي على `index_name` و `index_value`.
6. الاستعلام عن Cassandra:
```sql
SELECT * FROM rows
WHERE collection = 'X'
AND schema_name = 'Y'
AND index_name = '<frompayload>'
AND index_value = <frompayload>
```
7. إرجاع الصفوف المطابقة.
#### اختياري: التصفية حسب اسم الفهرس.
يمكن للاستعلامات اختيارياً أن تقوم بالتصفية باستخدام `index_name` في Qdrant للبحث في حقول محددة فقط:
**"ابحث عن أي حقل يطابق 'Chestnut'"** → ابحث في جميع المتجهات في المجموعة.
**"ابحث عن 'street_name' الذي يطابق 'Chestnut'"** → قم بالتصفية حيث `payload.index_name = 'street_name'`.
#### البنية.
تتبع تضمينات الصف النمط **المكون من مرحلتين** المستخدم في GraphRAG (تضمينات الرسم البياني، تضمينات المستندات):
**المرحلة 1: حساب التضمين** (`trustgraph-flow/trustgraph/embeddings/row_embeddings/`) - تستهلك `ExtractedObject`، وتحسب التضمينات عبر خدمة التضمينات، وتُخرج `RowEmbeddings`.
العثور على "CHESTNUT ST" عندما يبحث المستخدم عن "Chestnut Street"
استرجاع بيانات الصف بأكملها مع جميع الحقول
الجمع بين التشابه الدلالي والوصول إلى البيانات المنظمة
### استيعاب بيانات الصف
سيتم تأجيله إلى مرحلة لاحقة. سيتم تصميمه جنبًا إلى جنب مع تغييرات الاستيعاب الأخرى.
## التأثير على التنفيذ
### تحليل الحالة الحالية
يحتوي التنفيذ الحالي على مكونين رئيسيين:
| المكون | الموقع | الأسطر | الوصف |
|-----------|----------|-------|-------------|
| خدمة الاستعلام | `trustgraph-flow/trustgraph/query/objects/cassandra/service.py` | ~740 | كتلة واحدة: توليد مخطط GraphQL، تحليل المرشحات، استعلامات Cassandra، معالجة الطلبات |
| الكاتب | `trustgraph-flow/trustgraph/storage/objects/cassandra/write.py` | ~540 | إنشاء جدول لكل مخطط، فهارس ثانوية، إدراج/حذف |
**نمط الاستعلام الحالي:**
```sql
SELECT * FROM {keyspace}.o_{schema_name}
WHERE collection = 'X' AND email = 'foo@bar.com'
ALLOW FILTERING
```
**نمط استعلام جديد:**
```sql
SELECT * FROM {keyspace}.rows
WHERE collection = 'X' AND schema_name = 'customers'
AND index_name = 'email' AND index_value = ['foo@bar.com']
```
### التغييرات الرئيسية
1.**تبسيط دلالات الاستعلام**: المخطط الجديد يدعم فقط المطابقات الدقيقة على `index_value`. مرشحات GraphQL الحالية (`gt`، `lt`، `contains`، إلخ) إما:
تصبح تصفية لاحقة على البيانات المُرجعة (إذا كانت لا تزال مطلوبة)
يتم إزالتها لصالح استخدام واجهة برمجة تطبيقات التضمينات للمطابقة التقريبية
2.**كود GraphQL مرتبط ارتباطًا وثيقًا**: يحتوي `service.py` الحالي على توليد أنواع Strawberry، وتحليل المرشحات، والاستعلامات الخاصة بـ Cassandra. إضافة قاعدة بيانات أخرى ستؤدي إلى تكرار حوالي 400 سطر من كود GraphQL.
### إعادة الهيكلة المقترحة
تتكون إعادة الهيكلة من جزأين:
#### 1. فصل كود GraphQL
استخراج مكونات GraphQL القابلة لإعادة الاستخدام إلى وحدة مشتركة: