DanLevy.net

البحث المتجه الدلالي ومواضيع أخرى لكسب الأصدقاء والعشاق

المشهد الكامل للبحث: الدقة، التقريب، الدلالية، والهجين — ومتى ندمجهم جميعًا.

البحث ليس شيئًا واحدًا، والبحث الدلالي ليس بديلاً لبقية الأنواع.

“العثور على مستخدم بالبريد الإلكتروني dan@example.com” و”ابحث لي عن مقالات حول تصحيح الأخطاء كمطور جديد” يُوصفان كلاهما بالبحث، لكنهما لا يشتركان تقريبًا في أي شيء كمشكلة هندسية. الأول له إجابة صحيحة ويتطلب عملية بحث في الفهرس بـ O(log n). الثاني لا يمتلك إجابة صحيحة — فقط صلة — ويتطلب فهم اللغة والنية والمعنى.

المهندسون الذين يملكون أقوى الحُجج حول قرارات البحث — الذين يفوزون بالجدال ويطلقون النظام الصحيح — هم الذين يدركون المشهد بالكامل. يعرفون أي أداة يجب أن يستخدموها ولماذا، ويمكنهم شرح ذلك بوضوح.

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

النصف المعجمي والضبابي من الصورة — tsvector، pg_trgm، pg_search — موجود في دليل بحث النص في PostgreSQL 2026.

المصطلحات لمحة سريعة

Embedding — قائمة كثيفة من الأعداد العائمة التي ينتجها نموذج، تمثل قطعة نصية (أو صورة، صوت، إلخ) كنقطة في فضاء عالي الأبعاد. المحتوى المتعلق دلاليًا يقترب؛ المحتوى غير المتعلق يبتعد.

Lexical search — بحث يعتمد على مطابقة الكلمات والرموز الدقيقة. سريع، حتمي، وصحيح للمصطلحات المعروفة. لا يفهم المرادفات أو الصياغات البديلة أو المكافئات عبر اللغات.

Semantic search — بحث يعتمد على المعنى بدلاً من الرموز. يمكن لاستعلام مثل “كيف أتعامل مع مهلات الوقت” أن يطابق مستندًا بعنوان “تكوين سياسات إعادة المحاولة” دون أي كلمات مشتركة، لأن تمثيلاتهما المتجهية قريبة هندسيًا.

المتجه — قائمة من الأرقام. في سياق البحث، هو ناتج نموذج التضمين. «بحث المتجهات» يجد المتجهات الأقرب إلى متجه الاستعلام عبر المسافة الهندسية.

بحث النص الكامل (FTS) — البحث اللغوي المدمج في PostgreSQL، المدعوم بـ tsvector / tsquery. يقوم بتقسيم النص إلى رموز، وتطبيق الجذور، وفهرسة النص لاستعلامات الكلمات المفتاحية. قوي للنصوص النثرية والبحث عن المصطلحات الدقيقة؛ لكنه أعمى عن المعنى.

BM25 — خوارزمية ترتيب للبحث اللغوي (تُستخدم في Elasticsearch، Qdrant، وغيرها). تُحسب الدرجات بناءً على تكرار المصطلح مع وزن ندرته عبر المجموعة. أفضل من المطابقة البسيطة للكلمات المفتاحية؛ لكنه يظل لغويًا.

HNSW (Hierarchical Navigable Small World) — الفهرس التقريبي القياسي لأقرب الجيران في بحث المتجهات. يبني رسمًا بيانيًا متعدد الطبقات للقرابة لتوفير استعلامات تشابه سريعة وعالية الاستدعاء. يستخدمه pgvector، Qdrant، Weaviate، ومعظم الأنظمة الأخرى.

RRF (Reciprocal Rank Fusion) — خوارزمية لدمج قوائم النتائج المرتبة من أنظمة استرجاع متعددة. تعتمد فقط على موضع الترتيب — لا تحتاج إلى تطبيع الدرجات. النتيجة التي تحتل مرتبة عالية في كل من قوائم FTS والمتجه تحصل على درجة مركبة أقوى من تلك التي تتفوق في واحدة فقط.


ما يفعله البحث الدلالي فعليًا

تحويلات المتجهات تُحوِّل النص (أو الصور، الصوت، إلخ) إلى قائمة من الأرقام — نقطة في فضاء عالي الأبعاد. يتم تدريب نموذج التضمين بحيث تكون النصوص ذات الصلة الدلالية قريبة من بعضها في ذلك الفضاء. «Dog» و«canine» يقتربان. «Running a marathon» و«running a Python script» يبتعدان رغم اشتراكهما في كلمة «running».

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

هذا يعني:

البحث المعجمي (tsvector، pg_trgm) لا يستطيع فعل أي من ذلك. فهو يعمل على الكلمات والحروف، وليس على المعنى. الأدوات ليست قابلة للاستبدال — كل منها يحل مشكلة مختلفة.


متى يتفوق pgvector

بناء RAG. الاسترجاع المعزز للتوليد (Retrieval‑Augmented Generation) يجلب أجزاء المستند التي يكون معناها أقرب إلى سؤال المستخدم، ثم يمررها إلى نموذج اللغة كسياق. خطوة الاسترجاع هذه هي عملية متجهية. البحث النصي الكامل سيفوت الصيغ المعادلة، المرادفات، والتطابقات المفاهيمية التي قد يعبر عنها الجزء ذي الصلة بطريقة مختلفة. ميزة pgvector مقارنةً بمخزن متجهات مستقل هي أنه يعمل داخل قاعدة PostgreSQL الحالية — لا حاجة لخدمة منفصلة للنشر، التشغيل، أو مزامنة البيانات.

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

العثور على عناصر مشابهة. منتجات مرتبطة، تذاكر دعم مشابهة، تقارير أخطاء مكررة، مقالات قد تعجبك أيضاً. “ابحث عن مشاكل مشابهة لهذه” هو بحث أقرب جارٍ — يتم تضمين العنصر، ثم العثور على جيرانه الهندسيين. تحذير مهم: البحث المتجهي يعيد دائماً نتائج، حتى عندما لا يكون هناك تشابه حقيقي. لحالات إزالة التكرار والتوصية، يجب تصفية النتائج بحد أدنى للتشابه (مثلاً، تشابه جيبي ≥ 0.80) لتجنب إظهار تطابقات منخفضة الثقة كأنها ذات معنى.

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

البحث متعدد اللغات. نماذج التضمين متعددة اللغات تُطابق المحتوى الدلالي المكافئ عبر اللغات إلى متجهات قريبة. استعلام بالإسبانية عن “perder peso” يمكن أن يطابق مقالة إنجليزية حول “عادات فقدان الوزن المستدامة” — لا توجد رموز مشتركة، لكن المعنى الأساسي هو نفسه. البحث النصي الكامل يتطلب إعداد قواميس لكل لغة ويتعامل مع الاستعلامات عبر اللغات بشكل ضعيف. pg_trgm لا يهمه اللغة لكنه يعتمد على الشكل الكتابي، وليس الدلالي.

إعداد pgvector

من تثبيت الامتداد إلى استعلام التشابه، الإعداد يتكون من بضع جمل SQL فقط:

CREATE EXTENSION IF NOT EXISTS vector;
ALTER TABLE documents ADD COLUMN embedding vector(1536);
-- HNSW هو عادة الفهرس الأول الذي نجربه لمجموعات البيانات المتوسطة الحجم
CREATE INDEX documents_embedding_idx
ON documents USING hnsw (embedding vector_cosine_ops);
-- استعلام البحث الدلالي
SELECT id, title, 1 - (embedding <=> $1::vector) AS similarity
FROM documents
ORDER BY embedding <=> $1::vector
LIMIT 10;

<=> هو مسافة جيبية. 1 - cosine_distance يعطي تشابه جيبي (1.0 = متطابق تمامًا، 0.0 = عمودي). بالنسبة إلى ivfflat (البديل الأقدم الأسرع في الإنشاء)، استخدم lists = sqrt(row_count) كنقطة انطلاق.

ما لا يتقنه pgvector جيدًا


البحث الهجين: الحالة التي تحتاج كلاهما

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

المستخدمون الذين يبحثون عن “how to configure timeouts” يحتاجون إلى مطابقة مفهومية: مقالة بعنوان “Setting retry policies and connection limits” لا تشترك في أي كلمة مفتاحية لكنها بالضبط ما يحتاجونه.

نفس المستخدمين يبحثون أيضًا عن withRetry(), ECONNRESET, و ERR_SOCKET_TIMEOUT. يجب أن تظهر هذه السلاسل الدقيقة — المطابقة الدلالية قد لا تجدها بموثوقية، وإيجاد إيجابي زائف (مفهومي مشابه لكنه ليس الـ API الصحيح) يكون مضللًا فعليًا.

البحث الدلالي يتعامل مع الاستعلامات المفهومية. FTS يتعامل مع المصطلحات الدقيقة. لا أحد منهما يتقن كليهما بمفرده.

الحل هو البحث الهجين: تشغيل كلاهما ودمج النتائج.

دمج الرتبة العكسية

دمج الرتبة العكسية (RRF) هو الخوارزمية القياسية لدمج القوائم المرتبة من أنظمة استرجاع مختلفة. لا يتطلب تطبيع الدرجات بين الأنظمة — فهو يستخدم فقط مواضع الرتبة. النتيجة التي تظهر مرتبة عالية في كلا القائمتين تحصل على درجة مركبة أقوى من تلك التي تتفوق فقط في واحدة.

WITH fts_results AS (
SELECT id,
ROW_NUMBER() OVER (ORDER BY ts_rank(search_vector, query) DESC) AS rank
FROM documents, to_tsquery('english', $1) query
WHERE search_vector @@ query
LIMIT 50
),
vector_results AS (
SELECT id,
ROW_NUMBER() OVER (ORDER BY embedding <=> $2::vector) AS rank
FROM documents
ORDER BY embedding <=> $2::vector
LIMIT 50
),
rrf AS (
SELECT
COALESCE(f.id, v.id) AS id,
COALESCE(1.0 / (60 + f.rank), 0) +
COALESCE(1.0 / (60 + v.rank), 0) AS rrf_score
FROM fts_results f
FULL OUTER JOIN vector_results v ON f.id = v.id
)
SELECT d.id, d.title, rrf.rrf_score
FROM rrf
JOIN documents d ON d.id = rrf.id
ORDER BY rrf_score DESC
LIMIT 10;

العدد 60 في المقام هو ثابت RRF. القيم الأعلى تخفّف من الفروقات بين مواضع الرتبة؛ القيم الأقل تضخمها. القيمة الافتراضية 60 تعمل جيدًا لمعظم أنواع المحتوى.

يتجنّب RRF مشكلة تطبيع ts_rank (درجة تعتمد على تردد اللوغاريتم) مقابل مسافة جيبية (مقياس هندسي). لا يمكن مقارنتهما. يقتصر RRF على سؤال واحد: “ما مدى ارتفاع ظهور هذه النتيجة في كل قائمة؟“

البحث الهجين مع الـ Trigrams أيضًا

للبحث الموجه للمستخدم على محتوى مختلط — حيث قد يبحث المستخدم عن اسم شخص، مفهوم، أو مصطلح دقيق في نفس الجلسة — يتيح الدمج الثلاثي التعامل مع جميع الحالات:

WITH trgm_results AS (
SELECT id,
ROW_NUMBER() OVER (ORDER BY similarity(title, $1) DESC) AS rank
FROM documents
WHERE title % $1
LIMIT 50
),
fts_results AS (
SELECT id,
ROW_NUMBER() OVER (ORDER BY ts_rank(search_vector, to_tsquery('english', $1)) DESC) AS rank
FROM documents
WHERE search_vector @@ to_tsquery('english', $1)
LIMIT 50
),
vector_results AS (
SELECT id,
ROW_NUMBER() OVER (ORDER BY embedding <=> $2::vector) AS rank
FROM documents
ORDER BY embedding <=> $2::vector
LIMIT 50
),
rrf AS (
SELECT
COALESCE(t.id, f.id, v.id) AS id,
COALESCE(1.0 / (60 + t.rank), 0) +
COALESCE(1.0 / (60 + f.rank), 0) +
COALESCE(1.0 / (60 + v.rank), 0) AS rrf_score
FROM trgm_results t
FULL OUTER JOIN fts_results f ON t.id = f.id
FULL OUTER JOIN vector_results v ON COALESCE(t.id, f.id) = v.id
)
SELECT d.id, d.title, rrf.rrf_score
FROM rrf
JOIN documents d ON d.id = rrf.id
ORDER BY rrf_score DESC
LIMIT 10;

هذا يعالج: مطابقة الأسماء غير الدقيقة (trigrams)، مطابقة الكلمات المفتاحية الدقيقة (FTS)، والاستعلامات المفهومية (vector). يمكن لصندوق بحث واحد أن يخدم جميع نوايا المستخدم الثلاث.


بنى هجينة متعددة الطبقات

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

Surfaceما الذي يستعلم عنه المستخدمونالطبقات الموصى بها
بحث في المدونات / الوثائقكلمات مفتاحية + مفاهيمFTS + pgvector (RRF)
البحث عن اسم المستخدم / العميلأسماء مع أخطاء إملائيةpg_trgm
بحث عن منتجاتأسماء، أوصاف، “مشابه لـ”pg_trgm + FTS + pgvector
كشف التكرار في تذاكر الدعم“مشكلات مشابهة لهذه”pgvector فقط
بحث داخلي عن SKU / طلباتمعرفات دقيقةفهرس B‑tree
RAG على قاعدة معرفة ضخمةأسئلة بلغة طبيعيةpgvector (مستندات مقطعة)
“قد يعجبك أيضاً” في التجارة الإلكترونيةتشابه سلوكي + دلاليpgvector
الإكمال التلقائيبادئة، تحمل تسامحاً مع الأخطاء الإملائيةpg_trgm

هذه ليست سيناريوهات افتراضية. معظم التطبيقات التي تتعامل مع محتوى كثيف تحتاج على الأقل إلى سطحين بحثيين مميزين بأشكال استعلام مختلفة. الإغراء يكون غالباً باختيار نهج واحد واستخدامه في كل مكان — عادةً البحث المتجهي الآن، لأنه الخيار الشائع. هذا يؤدي إلى توليد embeddings مكلفة لمشكلات كان من الممكن حلها بفهرس trigram أسرع، أرخص، وأكثر دقة.

قاعدة الإبهام

أضف طبقة عندما تظهر حالة فشل لا تستطيع الطبقة الحالية معالجتها:


إذا كنت بحاجة إلى مخزن متجهي مخصص

pgvector يتعامل مع معظم عمليات البحث في التطبيقات قبل أن تحتاج إلى قاعدة بيانات أخرى. الحد التقريبي يعتمد على عدد المتجهات، إعدادات الفهرس، معدل الكتابة، الفلاتر، العتاد، والتزامن، لذا اعتبر أي قاعدة “أقل من 10 ملايين متجه” مجرد افتراض مبدئي للقياس، وليس حدًا للمنتج. عندما تتجاوز ذلك فعليًا — تزامن عالي جداً، متطلبات زمن استجابة p99 منخفضة جداً، مليارات المتجهات، أو حاجة حقيقية لعزل متعدد المستأجرين — يصبح مشهد قواعد البيانات المتجهية المخصصة واسعًا ويستحق الفهم.

ما تعنيه أعمدة المصفوفة فعليًا

البحث الهجين يعني تشغيل بحث BM25 بالكلمات المفتاحية والبحث المتجهي في استعلام واحد، ثم دمجهما عبر RRF. بدون ذلك، إما تختار وضع بحث واحد أو تقوم بدمج استعلامين بنفسك.

المتجهات المتناثرة تتجاوز BM25. متجه SPLADE المتناثر يحتوي على ~30,000 بُعد (واحد لكل مصطلح في المفردات)، ~98 % أصفار. المواقع غير الصفرية تخبرك أي المصطلحات مهمة وكم مقدارها. استعلام “dogs” يوزن أيضاً “canine” و“pet” — دقة مستوى BM25 مع توسيع المصطلحات داخل فهرس المتجهات. إذا كان هذا العمود غير مفعّل، تحتاج طبقة FTS منفصلة لاستعلامات المصطلحات الدقيقة.

# SPLADE: ~30,000 dims, ~60 non-zero — only relevant vocabulary positions fire
def encode_splade(text: str) -> dict:
tokens = tokenizer(text, return_tensors="pt", truncation=True, max_length=512)
with torch.no_grad():
output = model(**tokens)
vec = torch.log1p(torch.relu(output.logits)).max(dim=1).values.squeeze()
return {"indices": vec.nonzero().squeeze().tolist(), "values": vec[vec != 0].tolist()}

SQL / شبيهة‑SQL هي في الأساس عن الترشيح. البحث المتجهي بدون ترشيح هو مجرد عرض توضيحي. لا يزال عليك تطبيق نطاق المستأجر، نطاقات التاريخ، الأذونات، ومرشحات الفئات. SQL الكامل (pgvector، LanceDB) يعبر عن ذلك إلى جانب عمليات الانضمام الحالية. قواعد البيانات المصممة خصيصاً تستخدم كائنات ترشيح JSON (Qdrant، Pinecone)، لغة استعلام DSL (Elasticsearch، Milvus)، أو GraphQL (Weaviate). كلها تعمل؛ يصبح SQL أكثر جاذبية مع تعقيد منطق الترشيح.

-- pgvector: vector similarity is just another expression
SELECT id, title, 1 - (embedding <=> $1) AS score
FROM documents
WHERE tenant_id = $2
AND category = ANY($3::text[])
AND created_at > NOW() - INTERVAL '90 days'
ORDER BY embedding <=> $1
LIMIT 10;
# Qdrant: equivalent filter as a Python object — same result, more ceremony
results = client.query_points(
collection_name="documents", query=query_embedding,
query_filter=models.Filter(must=[
models.FieldCondition(key="tenant_id", match=models.MatchValue(value=tenant_id)),
models.FieldCondition(key="category", match=models.MatchAny(any=categories)),
models.FieldCondition(key="created_at", range=models.DatetimeRange(gte=cutoff)),
]),
limit=10,
)

الطبيعي المتعدد الوسائط يعني أن قاعدة البيانات تُرفق نماذج تضمين للمحتوى غير النصي. تعطيها عنوان صورة خام؛ تتولى تحويلها إلى متجه. معظم القواعد غير مرتبطة بالتضمين — أنت تدير خط أنابيب التضمين. Marqo وWeaviate (عبر وحدات CLIP/ImageBind) يغلقان هذه الحلقة.

# Marqo: POST raw images, query with text — no external embedding step
mq.index("products").add_documents(
[{"id": "shoe-001", "image": "https://cdn.example.com/shoes/001.jpg"}],
tensor_fields=["image"]
)
results = mq.index("products").search(q="lightweight shoes for summer")
# Returns shoe-001 despite zero keyword overlap — CLIP handles the cross-modal match

الفهرس القائم على القرص هو رافعة تكلفة. فهارس HNSW المقيمة في الذاكرة قد تتطلب عدة جيجابايت من RAM لكل مليون متجه بأبعاد 1536 عندما تُحسب المتجهات الخام، وإجهاد الرسم البياني، والبيانات الوصفية. البدائل القابلة للتخزين على القرص (Milvus DiskANN، Elasticsearch DiskBBQ، صيغة Lance في LanceDB، طبقة التخزين الكائني في Turbopuffer) غالباً ما تُقايض بعض زمن الاستجابة مقابل خفض تكلفة البنية التحتية. لأعباء عمل RAG حيث يهيمن زمن استجابة النموذج بالفعل، غالباً ما يكون هذا القيد جديراً بالاختبار.

الحد الأقصى للأبعاد هو ترحيل مخفي في بنية النظام. text-embedding-3-large يستخدم 3072 بُعد، Jina v3 يمكنه إنتاج تضمينات أكبر، والنماذج البحثية تستمر في دفع الأبعاد أعلى. بعض الخدمات المدارة تنشر حدود أبعاد صريحة؛ أخرى توثق حدوداً عالية أو لا تضع حدًا عمليًا للنماذج الشائعة. تحقق من الوثائق الحالية قبل الالتزام. اختر ما يترك مساحة للنمو؛ ترحيل فهرس متجه لأنك صادفت سقف أبعاد هو سباق مرهق.

تم التحقق من صحة المعلومات مقابل وثائق المشاريع العامة وصفحات المنتجات في 8 مايو 2026. اعتبر الجدول أدناه أداة مساعدة في اتخاذ القرار، وليس بديلاً عن مراجعة الحدود الحالية، التسعير، وعلمات ميزات الخدمات المدارة.

المشهد العام

قاعدة البياناتالنشرالترخيصالبحث الهجينالمتجهات المتناثرةSQL / شبيهة‑SQLمتعدد الوسائطفهرس على قرصالحد الأقصى للأبعادالنقطة المثالية
pgvectorاستضافة ذاتية / مُدارة (Supabase, Neon, RDS)OSS (PostgreSQL)يدوي (RRF عبر SQL)✅ SQL كامل✅ HNSW على قرص16,000 تخزين؛ 2,000 مفهرسة vectorموجود بالفعل على Postgres؛ عدد متجهات متوسط
Qdrantاستضافة ذاتية / سحابةApache 2.0✅ BM25 أصلي✅ دعم ناضج❌ (REST/gRPC)65,535استعلامات مُرشحة على نطاق واسع؛ بيانات وصفية معقّدة
Weaviateاستضافة ذاتية / سحابةBSD 3✅ BM25 أصلي + RRF❌ (GraphQL / gRPC)✅ عبر الوحدات65,535أنماط وصول GraphQL؛ تضمين مدمج
Pineconeسحابة فقطProprietary✅ (أضيف 2024)✅ (بدون خادم)20,000بساطة مُدارة؛ لا فريق عمليات
Milvus / Zillizاستضافة ذاتية / سحابة (Zilliz)Apache 2.0✅ أصلي✅ شبيهة‑SQL (Milvus Query Language)✅ DiskANN32,768مقياس بمليارات؛ مؤسسات داخلية
Chromaمدمج / استضافة ذاتيةApache 2.065,535تطوير محلي ونمذجة أولية فقط
LanceDBمدمج / سحابةApache 2.0✅ SQL عبر DataFusion✅ أصلي✅ (صيغة Lance)غير محدودحافة / بدون خادم؛ بحيرة بيانات متعددة الوسائط
Oramaمدمج / سحابةApache 2.0✅ نص كامل + متجهمتنوعتطبيقات JS/edge؛ بحث خفيف للمواقع
Turbopufferسحابة فقط (بدون خادم)Proprietary✅ BM25 + متجه✅ (تخزين كائنات)16,000SaaS متعدد المستأجرين؛ ملايين المساحات الاسمية
Elasticsearchاستضافة ذاتية / Elastic CloudSSPL / AGPLv3✅ RRF + ELSER متناثر✅ (ELSER)✅ DSL الاستعلام✅ DiskBBQ4,096موجود بالفعل في مجموعة Elastic؛ بحث مؤسسي هجين
OpenSearchاستضافة ذاتية / مُدارة AWSApache 2.0✅ RRF + بحث عصبي✅ DSL الاستعلام✅ FAISS + HNSW16,000أصلي لـ AWS؛ بديل مفتوح المصدر لـ Elastic
Vespaاستضافة ذاتية / سحابةApache 2.0✅ أصلي✅ موترات / ترتيب لغوي✅ YQL✅ موتراتغير محدود عمليًابحث + ترتيب + توصية
ClickHouseاستضافة ذاتية / سحابةApache 2.0يدوي✅ SQL كامل✅ عمودي + HNSWمتنوعتحليلات/سجلات مع بحث متجه إلى جانب OLAP
MongoDB Atlasسحابة / استضافة ذاتيةSSPL✅ مدمج✅ MQL + تجميع✅ HNSW8,192موجود بالفعل على MongoDB؛ مستند + متجه في آن واحد
Redis (VSS)استضافة ذاتية / Redis CloudRSALv2 / SSPL✅ (RediSearch)❌ RAM‑only32,768زمن استجابة فائق القليل؛ طبقة تخزين مؤقت للبحث المتجهي
Marqoسحابة / استضافة ذاتيةApache 2.0✅ تركيز أصليمتنوعمتعدد الوسائط من الطرف إلى الطرف: صورة + نص + فيديو

بعض الأشياء التي لا تتناسب مع الجدول

تعدد المستأجرين في Turbopuffer مبني حول عدد كبير جدًا من المساحات الاسمية. رسالته العامة وقصص العملاء تبرز أعباء عمل مثل مجموعة Notion الضخمة ذات المساحات الاسمية الكثيفة. إذا كان كل مستخدم أو مؤسسة تحتاج إلى بحث متجهي معزول، يمكن لهذا النموذج تغيير الاقتصاديات، لكن لا يزال من الضروري اختبار شكل المستأجر الخاص بك.

وضع LanceDB المدمج هو أقرب شيء إلى “SQLite للبحث المتجهي”. يعمل داخل العملية، لا يتطلب خادمًا، ويعمل في Lambda وCloudflare Workers وبيئات الحافة. يجعل تنسيق Lance العمودي العملية المدمجة عملية على نطاق حقيقي.

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

Vespa هو ما تلجأ إليه عندما يكون الاسترجاع مجرد نصف المنتج. يجمع بين الاسترجاع المعجمي، والبحث عن أقرب الجيران، والمُتَجَهات، وتعبيرات الترتيب، والتجميع، والخدمة عبر الإنترنت. هذه القوة حقيقية، لكن تعقيد التشغيل والنمذجة كذلك. يناسب فرق البحث/التوصية أكثر من “إضافة بحث متجهي إلى تطبيق CRUD الخاص بي”.

ClickHouse يندرج في النقاش عندما يكون البحث مرتبطًا بالتحليلات. إذا كان مصدر الحقيقة لديك هو الأحداث أو السجلات أو الآثار أو المقاييس، فإن ClickHouse يحتفظ بمسافة المتجه، والتصفية، والتجميع، وفهرسة النص الكامل الجادة في محرك SQL واحد. ليس قاعدة بيانات متجهية مُصممة خصيصًا، لكنه غالبًا الإجابة الصحيحة المملة للاسترجاع التحليلي.

المتجهات المتناثرة هي الطريقة التي تحصل بها على مطابقة كلمات مفتاحية بجودة BM25 داخل فهرس المتجهات — دون تشغيل محرك نص كامل منفصل. Qdrant وElasticsearch لديهما تطبيقات ناضجة بشكل خاص هنا. إذا كان البحث الهجين أمرًا حاسمًا وكان بنية نظامين عائقًا، فإن دعم المتجهات المتناثرة هو ما يجب البحث عنه.

اختيار الوقت المناسب عندما تتجاوز قدرات pgvector


الشيء الوحيد الذي يجب عدم فعله

لا تستخدم البحث المتجهي كبحث نصي غير دقيق للأشياء التي لها إجابات صحيحة.

“اعثر لي على المستخدم بالبريد الإلكتروني dan@example.com” ليس مشكلة بحث متجهية. “اعثر على الطلب بالمعرف ORD-12345” ليس كذلك أيضًا. تضمين ORD-12345 والبحث بتشابه جيب التمام سيعيد شيئًا — لكنه قد يكون غير صحيح. المعرف له إجابة صحيحة. التطابق التقريبي على معرف هو خطأ.

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

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


الصورة الكاملة

معظم أنظمة البحث في الإنتاج تحتاج إلى أكثر من طبقة واحدة:

هذه ليست أدوات متنافسة. إنها مكملة. نظام بحث مُصمم جيدًا يختار الطبقة المناسبة لكل شكل استعلام — وعندما تتقاطع أشكال الاستعلامات، يشغل عدة طبقات ويجمع النتائج.

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