> ## Documentation Index
> Fetch the complete documentation index at: https://docs.conare.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# الكتابات والاستيعاب المجمّع

> دلالات إدراج الصفوف وتصحيح السمات والحذف، وتشفيرات المتجهات JSON وbase64 fp16، والدمج في الخلفية، ومسار الاستيعاب المجمّع الثنائي للمتجهات.

## دورة حياة الصف

ثلاث خطوات تغطي دورة الحياة المُفتاحة بالمُعرّف، وكلها عبر `POST /v1/namespaces/{ns}/query`:

```json theme={null}
{"UpsertN": {"id": "chunk-123", "label": "chunk", "props": {"text": "..."}, "vector": [0.1]}}
{"SetProps": {"props": {"project": "v2", "stale_key": null}}}
{"DeleteN": {"ids": ["chunk-123"]}}
```

* **`UpsertN`** — استبدال كامل للصف مُفتاحه `id` الخارجي. تُحذف الصفوف الموجودة بذلك المُعرّف، ثم يُدرج الصف الجديد. استبدال، لا دمج: عملية upsert بدون متجه لصف يحمل متجهاً تُسقط المتجه.
* **`SetProps`** — الكتابة فوق مفاتيح محددة على تدفق مطابق (ابدأ الاستعلام بـ `NWhere`)؛ قيمة `null` تُزيل المفتاح. لا يمكن تغيير `id` نفسه — يتطلب ذلك `UpsertN`. مناسب لإعادة كتابات السمات العرضية، غير مناسب لعدّادات لكل استعلام.
* **`DeleteN`** — حذف تدفق مطابق (`NWhere` → `DeleteN`)، أو مرِّر `ids` لحذف مباشر عبر المُعرّفات الخارجية.

## تشفيرات المتجهات

لكل صف، أحد تشفيرين على السلك (إرسال كليهما يُنتج `400`):

```json theme={null}
{"vector": [0.0123, -0.0456]}
{"vector_b64": "zcxMPZqZmb4K16M8..."}
```

`vector_b64` هو base64 للمتجه كمصفوفة **f32 بترتيب little-endian** — أصغر بحوالي 4× على السلك ويُفكّ باستخدام memcpy بدلاً من تحليل أعداد JSON. مُشفِّر Python:

```python theme={null}
base64.b64encode(np.asarray(vec, dtype="<f4").tobytes()).decode("ascii")
```

يُنتج كلا التشفيرين متجهات مخزنة متطابقة بت-بت ونتائج بحث متطابقة. البُعد ثابت من أول عملية كتابة تحمل متجهاً؛ عدم التطابق يُنتج `400`.

## الاستيعاب المجمّع: `POST /v1/namespaces/{ns}/bulk-vectors`

مسار البذر عالي الإنتاجية — إطار ثنائي واحد لكل طلب (`Content-Type: application/octet-stream`): ترويسة JSON صغيرة (`dims`, `label`, `ids`, خصائص مشتركة) يليها قيم **fp16 موحّدة L2** بترتيب رئيسي حسب الصف. مقارنة بـ JSON+base64، يتجنب هذا إعادة تشفير حمولات بحجم عدة جيجابايت عدة مرات.

### تحميل آمن عند إعادة التشغيل

تمرر المحمّلات القابلة للاستئناف `?expected_generation=<G>&expected_rows=<N>`. يُقبل الإطار فقط عندما تكون مساحة الأسماء بالضبط في تلك الحالة:

* تم بالفعل تثبيت الإطار نفسه → `200` مع `"replayed": true` و`request_fingerprint` المطابق — لا صفوف مكررة.
* حمولة مختلفة في الموضع نفسه → `409 write_conflict`.
* تُعيد الكتابات الشرطية الناجحة `request_fingerprint`, `rows_before`, `rows_after` — سجّل نقطة تحقق دفعتك فقط بعد استلام أحد هذه الإيصالات.

هذا يجعل "تعطُّل، إعادة تشغيل، إعادة إرسال" هي قصة الاستئناف بأكملها: لا مهام استيراد لمتابعتها.

## الدمج

الدمج التلقائي هندسي، لذا يظل إجمالي عمل الدمج خطياً بالنسبة للبايتات المُستوعبة. أنهِ أي تحميل مجمّع بدمج صريح — أرسل `"compact": true` على المستوى الأعلى من **آخر** طلب كتابة:

```json theme={null}
{"request_type": "write", "compact": true, "query": {"...": "..."}}
```

تُبلّغ الاستجابة عن `"compacted": true/false`. يبني الدمج أيضاً فهرس ANN بمجرد أن يصبح الجدول كبيراً بما فيه الكفاية؛ الصفوف المكتوبة بعد لقطة الفهرس تُدمج في النتائج بالقوة الغاشمة، لذا لا يُضحَّى بالحداثة أبداً.

## إزالة تكرار مصدر مجمّع

تُضاف الإطارات المجمّعة بشكل أعمى بحكم التصميم — مصدر يحمل مُعرّفات مكررة يُنزلها بصمت، والتكرارات تحرق فتحات top-k. `{"DedupN": {}}` يوفّق مخزناً مع عقد تفرد المُعرّف الخارجي (يحتفظ بآخر صف مكتوب لكل مُعرّف)، و`{"DedupN": {"dry_run": true}}` هو تدقيق تعدادي فقط يجب على أي تحميل مجمّع تشغيله عندما لا يستطيع مصدره إثبات تفرد المُعرّف — إجمالي عدد صفوف مطابق لا يمكن أن يكشف التكرارات المختبئة داخله.

## قواعد إعادة المحاولة

يمكن دائماً إعادة محاولة القراءات بعد فشل النقل. بالنسبة للكتابات، فقط الإطارات المجمّعة الشرطية قابلة لإعادة المحاولة تلقائياً (إطار متطابق + معاملات CAS → الإيصال الأصلي أو `replayed: true`). لا تُعِد أبداً كتابة غير مشروطة بشكل أعمى بعد فقدان الاستجابة — وفّق الحالة أولاً.
