بحث نصي كامل في PostgreSQL يكفي للعديد من التطبيقات. استخدم قاعدة قرار بسيطة، استعلام بداية، وقائمة فهرسة لتعرف متى تضيف محرك بحث.

معظم الناس لا يطلبون "بحث نص كامل" بالاسم. يطلبون خانة بحث تبدو سريعة وتجد ما كانوا يقصدون في الصفحة الأولى. إذا كانت النتائج بطيئة أو صاخبة أو مرتبة بطريقة غريبة، المستخدمون لا يهتمون إن كنت استخدمت PostgreSQL full-text search أو محركًا منفصلًا — فقط يتوقفون عن الوثوق بالبحث.
هذا قرار واحد: احتفظ بالبحث داخل Postgres، أم أضيف محرك بحث مخصص. الهدف ليس دقة مثالية، بل أساس قوي يُشحن بسرعة، سهل التشغيل، وجيد بما يكفي لكيفية استخدام تطبيقك فعليًا.
للعديد من التطبيقات، PostgreSQL full-text search يكفي لفترة طويلة. إذا كانت لديك بضعة حقول نصية (عنوان، وصف، ملاحظات)، ترتيب أساسي، وفلتر أو فلتران (حالة، فئة، مستأجر)، فيمكن لـ Postgres التعامل مع ذلك دون بنية تحتية إضافية. تحصل على أجزاء متحركة أقل، نسخ احتياطية أبسط، وحوادث أقل من نوع "لماذا البحث متوقف بينما التطبيق يعمل؟".
"الكافي" عادةً يعني أنك تستطيع تحقيق ثلاثة أهداف في نفس الوقت:
مثال ملموس: لوحة SaaS حيث يبحث المستخدمون عن المشاريع بالاسم والملاحظات. إذا أعاد استعلام مثل "onboarding checklist" المشروع الصحيح ضمن أعلى 5، في أقل من ثانية، ولست تضبط المحللات أو تعيد فهرسة باستمرار، فذلك "كافٍ". عندما لا تستطيع تحقيق تلك الأهداف دون إضافة تعقيد، عندها يصبح قرار "البحث المدمج مقابل محرك البحث" سؤالًا حقيقيًا.
الفرق بين الفرق غالبًا يتجلى في وصف الميزات بدلاً من النتائج. التحرك المفيد هو ترجمة كل ميزة إلى التكلفة لبنائها وضبطها وإبقائها موثوقة.
الطلبات المبكرة عادةً ما تبدو كالتالي: تحمل الأخطاء الإملائية، واجهات التجزئة والفلاتر، التمييز (highlights)، ترتيب "ذكي"، وإكمال تلقائي. للإصدار الأول، فصل ما هو ضروري عما هو مرغوب فيه. مربع البحث الأساسي عادةً يحتاج فقط لإيجاد العناصر ذات الصلة، التعامل مع أشكال الكلمات الشائعة (جمع، زمن)، احترام فلاتر بسيطة، والبقاء سريعًا مع نمو الجدول. هذا هو المكان الذي يبرع فيه PostgreSQL full-text search.
يتألق Postgres عندما يعيش المحتوى في حقول نصية عادية وتريد البحث بالقرب من بياناتك: مقالات المساعدة، المنشورات، تذاكر الدعم، الوثائق الداخلية، عناوين ووصف المنتجات، أو ملاحظات في سجلات العملاء. هذه في الغالب مشاكل "أوجد السجل الصحيح"، وليست "ابنِ منتج بحث".
الميزات المرغوبة هي حيث يتسلل التعقيد. تحمل الأخطاء الإملائية والإكمال التلقائي الغني عادةً يدفعانك نحو أدوات إضافية. الفئات ممكنة في Postgres، لكن إذا أردت العديد من الفئات، تحليلات عميقة، وعدّ فوري عبر مجموعات بيانات هائلة، فالمحرك المخصص يصبح أكثر جاذبية.
التكلفة المخفية نادرًا ما تكون رسوم الترخيص. هي النظام الثاني. بمجرد إضافة محرك بحث، تضيف أيضًا مزامنة بيانات وإعادة تعبئة (ومشاكلها)، مراقبة وترقيات، عمل دعم "لماذا يظهر البحث بيانات قديمة؟"، ومجموعتي مفاتيح ضبط صلة.
إذا لم تكن متأكدًا، ابدأ بـ Postgres، اطلق شيئًا بسيطًا، وأضف محركًا آخر فقط عندما يكون هناك متطلب واضح لا يمكن تلبيته.
استخدم قاعدة ثلاث فحوص. إذا نجحت في الثلاثة، ابقَ مع PostgreSQL full-text search. إذا فشلت في واحدة بشدة، فكّر في محرك بحث مخصص.
احتياجات الصلة: هل نتائج "جيدة بما يكفي" مقبولة، أم أنك تحتاج ترتيبًا شبه مثالي عبر العديد من الحالات الحدية (أخطاء إملائية، مرادفات، "البحثون أيضًا بحثوا عن"، نتائج مخصصة)؟ إذا كنت تتسامح مع ترتيب غير مثالي أحيانًا، فـ Postgres عادة يعمل.
حجم الاستعلامات والكمون: كم عدد عمليات البحث في الثانية تتوقع عند الذروة، وما ميزان الكمون الحقيقي لديك؟ إذا كان البحث جزءًا صغيرًا من الحركة ويمكن إبقاء الاستعلامات سريعة بفهارس مناسبة، فـ Postgres مناسب. إذا أصبح البحث عبئًا كبيرًا وبدأ ينافس القراءات والكتابات الأساسية، فهذه إشارة تحذير.
التعقيد: هل تبحث في حقل أو حقلين نصيين، أم تجمع العديد من الإشارات (وسوم، فلاتر، تراجع زمني، شعبية، أذونات) وعدة لغات؟ كلما زاد تعقيد المنطق، زاد الاحتكاك داخل SQL.
نقطة بداية آمنة: اطلق معيارًا في Postgres، سجّل الاستعلامات البطيئة وعمليات البحث التي لم تُرجع نتائج، وبعدها قرر. كثير من التطبيقات لا تتخطاها أبدًا، وتتجنب تشغيل ومزامنة نظام ثانٍ مبكرًا.
علامات حمراء عادةً تشير لمحرك مخصص:
علامات خضراء للبقاء في Postgres:
PostgreSQL full-text search هي طريقة مدمجة لتحويل النص إلى شكل يمكن للقاعدة البحث فيه بسرعة، دون مسح كل صف. تعمل بشكل أفضل عندما يكون محتواك في Postgres وتريد بحثًا سريعًا وجيدًا وعمليات متوقعة.
ثلاث قطع تستحق المعرفة:
ts_rank (أو ts_rank_cd) لوضع الصفوف الأكثر صلة أولًا.تكوين اللغة مهم لأنه يغير كيفية تعامل Postgres مع الكلمات. مع الإعداد الصحيح، يمكن أن تتطابق "running" و"run" (stemming)، ويمكن تجاهل كلمات الحشو الشائعة (stop words). مع إعداد خاطئ، قد يبدو البحث معطلاً لأن صياغة المستخدم العادية لم تطابق ما فُهرس.
مطابقة البادئة هي الميزة التي يلجأ إليها الناس عندما يريدون سلوك "كتابة تلقائي" بسيطًا، مثل مطابقة "dev" لـ "developer". في Postgres FTS، يُحقق ذلك عادةً بواسطة عامل بادئة (مثل term:*). يمكن أن يحسن الجودة المُدركة، لكنه غالبًا يزيد عبء العمل لكل استعلام، لذا عالِجه كترقية اختيارية، ليس كافتراضي.
ما لا تحاول Postgres أن تكونه: منصة بحث كاملة بكل ميزة. إذا كنت تحتاج إلى تصحيح إملائي غامض، إكمال متقدم، تعلم للترتيب، محولات تحليل معقدة لكل حقل، أو فهرسة موزعة عبر عقد كثيرة، فأنت خارج نطاق الامتياز المدمج. مع ذلك، لعديد من التطبيقات، PostgreSQL full-text search يعطي معظم ما يتوقعه المستخدمون مع أجزاء متحركة أقل.
هنا شكل صغير وواقعي للمحتوى الذي تريد البحث فيه:
-- Minimal example table
CREATE TABLE articles (
id bigserial PRIMARY KEY,
title text NOT NULL,
body text NOT NULL,
updated_at timestamptz NOT NULL DEFAULT now()
);
خط أساس جيد لـ PostgreSQL full-text search هو: بناء استعلام من ما كتبه المستخدم، فلترة الصفوف أولًا (عند الإمكان)، ثم ترتيب المطابقات المتبقية.
-- $1 = user search text, $2 = limit, $3 = offset
WITH q AS (
SELECT websearch_to_tsquery('english', $1) AS query
)
SELECT
a.id,
a.title,
a.updated_at,
ts_rank_cd(
setweight(to_tsvector('english', coalesce(a.title, '')), 'A') ||
setweight(to_tsvector('english', coalesce(a.body, '')), 'B'),
q.query
) AS rank
FROM articles a
CROSS JOIN q
WHERE
a.updated_at >= now() - interval '2 years' -- example safe filter
AND (
setweight(to_tsvector('english', coalesce(a.title, '')), 'A') ||
setweight(to_tsvector('english', coalesce(a.body, '')), 'B')
) @@ q.query
ORDER BY rank DESC, a.updated_at DESC, a.id DESC
LIMIT $2 OFFSET $3;
بعض التفاصيل التي توفر وقتًا لاحقًا:
WHERE قبل الترتيب (status، tenant_id، نطاقات التاريخ). تقوم بترتيب عدد أقل من الصفوف، فيظل سريعًا.ORDER BY (مثل updated_at ثم id). هذا يحافظ على ثبات الترقيم عند وجود نتائج متساوية.websearch_to_tsquery لمدخلات المستخدم. يتعامل مع الاقتباسات والعوامل البسيطة كما يتوقع الناس.بعد أن يعمل هذا القاعدة، انقل التعبير to_tsvector(...) إلى عمود مخزن. هذا يتجنب إعادة حسابه عند كل استعلام ويسهّل الفهرسة.
معظم قصص "PostgreSQL full-text search بطيء" تتلخص في شيء واحد: القاعدة تبني وثيقة البحث عند كل استعلام. أصلح ذلك أولًا بتخزين tsvector مُسبق وفهرسته.
tsvector: عمود مولَّد أم مشغِّل؟العمود المولَّد هو الخيار الأبسط عندما تُبنى وثيقة البحث من أعمدة في نفس الصف. يظل صحيحًا تلقائيًا ومن الصعب نسيانه أثناء التحديثات.
استخدم tsvector مُدار بالمشغلات عندما تعتمد الوثيقة على جداول مرتبطة (مثال: دمج صف منتج مع اسم فئته)، أو عندما تريد منطقًا مخصصًا يصعب التعبير عنه كتعبير مولَّد. المشغلات تضيف أجزاء متحركة، فحافظ عليها صغيرة واختبرها.
انشئ فهرس GIN على عمود tsvector. هذا هو الأساس الذي يجعل PostgreSQL full-text search يبدو فوريًا لبحث التطبيقات النموذجية.
إعداد يعمل لكثير من التطبيقات:
tsvector في نفس الجدول الذي تبحثه غالبًا.tsvector.@@ ضد tsvector المخزن، لا to_tsvector(...) المحسوب على الطاير.VACUUM (ANALYZE) بعد خلفيات ضخمة حتى يفهم المخطط الفهرسي التغييرات.الحفاظ على المتجه في نفس الجدول عادةً ما يكون أسرع وأبسط. جدول بحث منفصل قد يكون منطقيًا إذا كان الجدول الأساسي يتعرض لكتابات كثيرة جدًا، أو إذا كنت تفهرس مستندًا مدمجًا يمتد عبر جداول عديدة وتريد تحديثه بجدولك الزمني.
الفهارس الجزئية يمكن أن تساعد عندما تبحث فقط في مجموعة فرعية من الصفوف، مثل status = 'active'، مستأجر واحد في تطبيق متعدد المستأجرين، أو لغة محددة. تقلل حجم الفهرس ويمكن أن تسرع البحث، لكن فقط إذا تضمن استعلاماتك دائمًا نفس الفلتر.
يمكنك الحصول على نتائج جيدة بشكل مفاجئ مع PostgreSQL full-text search إذا أبقيت قواعد الملاءمة بسيطة ومتوقعة.
أسهل مكسب هو وزن الحقول: التطابقات في العنوان يجب أن تحسب أكثر من التطابقات في النص. ابنِ tsvector مُدمجًا حيث يُوزن العنوان أعلى من الوصف، ثم رتب باستخدام ts_rank أو ts_rank_cd.
إذا كنت تحتاج العناصر "الحديثة" أو "الشائعة" أن ترتفع، فافعل ذلك بحذر. تعزيز صغير مقبول، لكن لا تدعه يتجاوز صلة النص. نمط عملي: رتّب بالنص أولًا، ثم اكسر التعادل بالجدة، أو أضف مكافأة محدودة حتى لا يتفوق عنصر جديد غير ذي صلة على تطابق قديم ومثالي.
المرادفات ومطابقة العبارات هي حيث تختلف التوقعات غالبًا. المرادفات ليست تلقائية؛ تحصل عليها فقط إذا أضفت معجم مرادفات أو قاموسًا مخصصًا، أو توسع الاستعلام بنفسك (مثال: التعامل مع "auth" على أنه "authentication"). مطابقة العبارات أيضًا ليست افتراضية: الاستعلامات العادية تطابق الكلمات في أي مكان، لا "هذه العبارة بالذات". إذا كتب المستخدمون عبارات مقيدة أو أسئلة طويلة، فكّر في phraseto_tsquery أو websearch_to_tsquery لمطابقة أفضل.
المحتوى متعدد اللغات يحتاج قرارًا. إذا كنت تعرف لغة كل مستند، خزّنها وولّد tsvector بإعداد اللغة الصحيح (English، Russian، إلخ). إذا لم تعرفها، فالملاذ الآمن هو فهرستها بإعداد simple (بدون تجذير)، أو الاحتفاظ بمتجهين: واحد خاص باللغة عند المعرفة، وآخر simple للجميع.
للتحقق من الملاءمة، اجعلها صغيرة وموضوعية:
هذا عادةً يكفي لبحث صناديق التطبيقات مثل "القوالب"، "الوثائق"، أو "المشاريع".
معظم قصص "PostgreSQL full-text search بطيء أو غير ملائم" تأتي من بعض الأخطاء التي يمكن تجنبها. إصلاحها غالبًا أسهل من إضافة نظام بحث جديد.
فخ شائع هو معاملة tsvector كقيمة محسوبة تظل صحيحة بنفسها. إذا خزنت tsvector في عمود لكنك لا تحدّثه عند كل إدخال وتحديث، ستبدو النتائج عشوائية لأن الفهرس لم يعد يطابق النص. إذا حسبت to_tsvector(...) في الطاير داخل الاستعلام، قد تكون النتائج صحيحة لكنها بطيئة، وربما تفقد فائدة الفهرس.
طريقة أخرى للإضرار بالأداء هي الترتيب قبل تضييق مجموعة المرشحين. ts_rank مفيد، لكنه يجب عادةً أن يعمل بعد أن استخدم Postgres الفهرس لإيجاد الصفوف المطابقة. إذا حسبت الترتيب لجزء كبير من الجدول (أو انضممت إلى جداول أخرى أولًا)، يمكنك تحويل بحث سريع إلى مسح جدول.
يتوقع الناس أيضًا أن يتصرف "contains" مثل LIKE '%term%'. النجميات في البداية لا تتطابق جيدًا مع FTS لأن FTS معتمد على الكلمات (lexemes)، لا على سلاسل جزئية عشوائية. إذا احتجت بحثًا بالجزء للأكواد أو المعرفات الجزئية، استخدم أداة مختلفة لهذه الحالة (مثل فهرسة trigram) بدلاً من لوم FTS.
مشكلات الأداء غالبًا ما تأتي من معالجة النتائج، لا المطابقة. نمطان يجب مراقبتهما:
OFFSET كبير، مما يجعل Postgres يتخطى عددًا متزايدًا من الصفوف مع الترقيم.القضايا التشغيلية مهمة أيضًا. انتفاخ الفهارس (index bloat) يمكن أن يتراكم بعد الكثير من التحديثات، وإعادة الفهرسة قد تكون مكلفة إذا انتظرت حتى تصبح الأمور مؤلمة. قِس أزمنة الاستعلام الحقيقية (وتحقق من EXPLAIN ANALYZE) قبل وبعد التغييرات. بدون أرقام، من السهل "إصلاح" PostgreSQL full-text search بجعلها أسوأ بطريقة أخرى.
قبل أن تُحَمِّل PostgreSQL full-text search باللوم، شغّل هذه الفحوص. معظم أخطاء "بحث Postgres بطيء أو غير ملائم" تأتي من أساسيات مفقودة، لا من الميزة نفسها.
ابنِ tsvector حقيقيًا: خزّنه في عمود مولَّد أو مُدار، استخدم إعداد اللغة المناسب (english, simple, إلخ)، وطبق أوزانًا إذا خلطت الحقول (title > subtitle > body).
نقّح ما تفهرسه: اترك الحقول الصاخبة (المعرفات، النصوص الثابتة، نصوص التنقل) خارج tsvector، واقطع الحِزم الكبيرة إذا لم يبحث المستخدمون عنها.
أنشئ الفهرس الصحيح: أضف فهرس GIN على عمود tsvector وتأكد من أنه مستخدم في EXPLAIN. إذا كانت مجموعة فرعية فقط قابلة للبحث (مثال status = 'published')، ففهرس جزئي يمكن أن يقلل الحجم ويسرع القراءات.
حافظ على صحة الجداول: الصفوف الميتة (dead tuples) يمكن أن تبطئ مسح الفهرس. التنظيف الدوري (VACUUM) مهم، خاصة على المحتوى الذي يُحدَّث كثيرًا.
ضع خطة لإعادة الفهرسة: الترحيلات الكبيرة أو الفهارس المنتفخة أحيانًا تحتاج نافذة إعادة فهرسة مُدارة.
بمجرد أن تبدو البيانات والفهرس صحيحين، ركز على شكل الاستعلام. PostgreSQL full-text search سريع عندما يستطيع تضييق مجموعة المرشحين مبكرًا.
فلتر أولًا، ثم رتب: طبق فلاتر صارمة (tenant، اللغة، منشور، فئة) قبل الترتيب. ترتيب آلاف الصفوف التي ستُستبعد لاحقًا مضيعة للعمل.
استخدم ترتيبًا ثابتًا: رتب بحسب الدرجة ثم فاصل ثابت مثل updated_at أو id كي لا تقفز النتائج بين التحديثات.
تجنب "الاستعلام يفعل كل شيء": إذا احتجت مطابقة غامضة أو تحمل أخطاء، افعلها عمدًا (وقِس). لا تُجبِر المسارات على المسح المتسلسل عن طريق الخطأ.
اختبر استعلامات حقيقية: اجمع أفضل 20 بحثًا، تحقق من الملاءمة يدويًا، واحتفظ بقائمة نتائج متوقعة صغيرة لالتقاط التراجعات.
راقب المسارات البطيئة: سجّل الاستعلامات البطيئة، راجع EXPLAIN (ANALYZE, BUFFERS), وراقب حجم الفهرس ومعدل ضربة الكاش لتكتشف متى يغير النمو السلوك.
مركز مساعدة SaaS مكان جيد للبدء لأن الهدف بسيط: مساعدة الناس في العثور على المقالة التي تجيب عن سؤالهم. لديك بضعة آلاف مقالات، كل منها بعنوان، ملخص قصير، ونص. معظم الزوار يكتبون 2 إلى 5 كلمات مثل "reset password" أو "billing invoice".
مع PostgreSQL full-text search، هذا قد يبدو مكتملًا بسرعة مفاجئة. تخزن tsvector للحقل المدمج، تضيف فهرس GIN، وترتب بالملاءمة. النجاح يبدو كالتالي: النتائج تظهر في أقل من 100 مللي ثانية، أعلى 3 نتائج عادة صحيحة، ولا تحتاج لمراقبة مستمرة.
ثم يكبر المنتج. الدعم يريد فلترة حسب مجال المنتج، المنصة (ويب، iOS، Android)، والخطة (مجاني، محترف، أعمال). كتاب الوثائق يريدون مرادفات، "هل تقصد"، وتعامل أفضل مع الأخطاء الإملائية. التسويق يريد تحليلات مثل "البحثات التي لم تُرجع نتائج". تتصاعد الحركة ويصبح البحث من أكثر نقاط النهاية نشاطًا.
هذه إشارات أن محرك بحث مخصص قد يبرّر التكلفة:
مسار هجرة عملي هو الحفاظ على Postgres كمصدر للحقيقة حتى بعد إضافة محرك بحث. ابدأ بتسجيل استعلامات البحث وحالات "بدون نتيجة"، ثم شغّل وظيفة مزامنة غير متزامنة تنسخ الحقول القابلة للبحث فقط إلى الفهرس الجديد. شغل الاثنين بالتوازي لفترة وبدّل تدريجيًا بدلاً من المجازفة بالتبديل دفعة واحدة.
إذا كان بحثك في الأساس "وجد مستندات تحتوي هذه الكلمات" ومجموعة بياناتك ليست هائلة، فـ PostgreSQL full-text search عادةً يكفي. ابدأ هناك، اجعله يعمل، وأضف محركًا مخصصًا فقط عندما تستطيع تسمية الميزة المفقودة أو ألم القياس.
ملخص عملي:
tsvector، إضافة فهرس GIN، واحتياجات الترتيب لديك أساسية.خطوة عملية: نفّذ الاستعلام والفهارس المبدئية من الأقسام الأسبق، ثم سجّل بعض المقاييس البسيطة لأسبوع. تتبع p95 زمن الاستعلام، الاستعلامات البطيئة، وإشارة نجاح تقريبية مثل "بحث -> نقرة -> لا ارتداد فوري" (حتى عدّاد حدث بسيط يفيد). ستعرف بسرعة إن كنت بحاجة لملاءمة أفضل أو فقط لتحسين واجهة المستخدم (فلاتر، تمييز، مقتطفات أفضل).
ابدأ التخطيط لمحرك بحث مخصص عندما تصبح إحدى هذه النقاط متطلبًا حقيقيًا (ليس مرغوبًا): إكمال تلقائي قوي أو بحث فوري على كل ضغطة مفتاح بمقياس كبير، تحمل أخطاء قوي وتصحيح تهجئة، فلاتر وتجميعات مع عدّ سريع عبر حقول عديدة، أدوات ملاءمة متقدمة (مجموعات مرادفات، تعلم للترتيب، تعزيزات حسب الاستعلام)، أو حمل مستمر وكبير وفهارس ضخمة من الصعب إبقاؤها سريعة.
إذا أردت التقدم بسرعة في جانب الواجهة، يمكن أن تكون Koder.ai (koder.ai) طريقة مفيدة لنموذج واجهة البحث وواجهة برمجة التطبيقات عبر المحادثة، ثم تعدل بأمان باستخدام لقطات واسترجاع أثناء قياس ما يفعله المستخدمون فعليًا.
PostgreSQL full-text search "يكفي" عندما تستطيع تحقيق ثلاثة أمور معًا:
إذا استطعت تحقيق ذلك باستخدام tsvector مخزن + فهرس GIN، فأنت عادة في موقف جيد.
النصيحة الافتراضية هي البدء بـ PostgreSQL full-text search أولًا. يُنشر بسرعة أكبر، ويحافظ على البيانات والبحث في مكان واحد، ويجنبك بناء وصيانة خط فهرسة منفصل.
انتقل إلى محرك بحث مخصص عندما يكون لديك متطلب واضح لا تستطيع Postgres تلبيته جيدًا (مثل تحمل أخطاء الإملاء بجودة عالية، إكمال تلقائي غني، فلاتر/تجزئة مكثفة، أو حمل بحث يتنافس مع عمل قاعدة البيانات الأساسية).
قاعدة سريعة: ابقَ في Postgres إذا نجحت في هذه الفحوص الثلاثة:
إذا فشلت في واحدة بشكل واضح (خاصة ميزات الصلة مثل الأخطاء/الإكمال، أو حمل بحث مرتفع)، فكّر في محرك مخصص.
استخدم Postgres FTS عندما يكون بحثك غالبًا "إيجاد السجل الصحيح" عبر بضعة حقول مثل العنوان/النص/الملاحظات، مع فلاتر بسيطة (tenant وstatus وcategory).
يناسب ذلك مراكز المساعدة، الوثائق الداخلية، التذاكر، البحث في المقالات/المدونة، ولوحات SaaS التي يبحث المستخدمون فيها عن أسماء المشاريع وملاحظاتها.
شكل استعلام مبدئي جيد عادةً:
websearch_to_tsquery.خزن tsvector مُسبقًا وأضف فهرس GIN. هذا يتفادى إعادة حساب to_tsvector(...) على كل طلب.
إعداد عملي:
tsvector القابل للبحث في نفس الجدول الذي تستعلمه.استخدم عمود مولَّد عندما تكون وثيقة البحث مبنية من أعمدة في نفس الصف (بسيط وصحيح تلقائيًا).
استخدم عمود تُديره مشغلات عندما تعتمد نصوص البحث على جداول مرتبطة (مثل دمج منتج مع اسم فئة)، أو عندما تحتاج منطقًا مخصصًا يصعب التعبير عنه بتعبير مولَّد.
الخيار الافتراضي: عمود مولَّد أولًا، والمشغلات فقط عند الحاجة الحقيقية لتكوين عبر جداول.
ابدأ بقواعد ملاءمة متوقعة:
ثم تحقق باستخدام قائمة صغيرة من استعلامات المستخدم الحقيقية والنتائج المتوقعة في القمة.
FTS في Postgres يعتمد على الكلمات، ليس على السلاسل الجزئية. لذلك لن يتصرف مثل LIKE '%term%' للبحث عن أجزاء داخلية.
إذا كنت بحاجة إلى بحث بالجزء (مثل رموز المنتجات أو معرفات جزئية)، فتعامل معه بشكل منفصل (غالبًا باستخدام فهرسة trigram) بدلًا من إجبار FTS على فعل ما ليس مُصممًا له.
إشارات أنك تجاوزت قدرات Postgres FTS:
الطريق العملي: اجعل Postgres مصدر الحقيقة واستمر في ذلك حتى يصبح متطلب واضح يستدعي فهرسة غير متزامنة.
@@ مقابل tsvector مخزن.ts_rank/ts_rank_cd مع فاصل ثابت مثل updated_at, id.هذا يحافظ على النتائج ذات صلة، سريعة، ومستقرة في الترقيم.
tsvector_column @@ tsquery.هذا هو الإصلاح الأكثر شيوعًا عندما يبدو البحث بطيئًا.