كلنا نرتكب أخطاء: في هذه الحالة ، نتحدث عن استعلامات البحث. يتزايد عدد مواقع بيع السلع والخدمات إلى جانب احتياجات المستخدمين ، لكنهم لا يستطيعون دائمًا العثور على ما يبحثون عنه - فقط لأنهم يدخلون بشكل صحيح اسم المنتج الضروري. يتحقق حل هذه المشكلة من خلال تطبيق بحث غامض ، أي باستخدام الخوارزمية للعثور على أقرب القيم ، مع مراعاة الأخطاء أو الأخطاء المطبعية المحتملة للمستخدم. نطاق مثل هذا البحث واسع بما فيه الكفاية - تمكنا من العمل على البحث عن متجر كبير عبر الإنترنت في قطاع بيع المواد الغذائية بالتجزئة.
حالة البحث الأولي
تم تطوير المتجر عبر الإنترنت على منصة 1C-Bitrix: Site Management. لتنفيذ البحث ، استخدمنا وحدة بحث bitrix القياسية ومحرك النص الكامل للبحث عن sphinxsearch. في sphinxsearch ، تم استخدام نوع فهرس Real Time (RT) ، والذي لا يتطلب مصدر بيانات ثابت ، ولكن يمكن ملؤه في أي وقت في الوقت الحقيقي. يتيح لك ذلك تحديث فهرس البحث بمرونة دون إعادة الفهرسة بالكامل. نظرًا لأن فهرس RT يستخدم SphinxQL فقط كبروتوكول للاستعلام ، فقد تم التكامل من خلاله. SphinxQL هو بروتوكول استعلام يشبه mysql والذي ينفذ القدرة على الاتصال عبر عملاء mysql القياسيين ، مع توفير بناء جملة sql مع بعض القيود وخصائصه الخاصة. تستخدم وحدة البحث طلبات تحديد / إدراج / استبدال / حذف.
في نظام bitrix ، تم تنفيذ عملية فهرسة بيانات البضائع والفئات والعلامات التجارية. تم نقل المعلومات حول هذه الكيانات إلى أبو الهول ، والتي بدورها قامت بتحديث مؤشر RT. عند تحديث البيانات في المتجر على الإنترنت ، يتم تشغيل حدث يقوم بتحديث البيانات في Sphinx. يتم تنفيذ تناسق البيانات من خلال معرف الكيان في المتجر عبر الإنترنت.
عندما يبحث المستخدم في أحد المتاجر عبر الإنترنت ، فإن النظام يقدم طلبًا باستخدام عبارة بحث في Sphinx ويحصل على معرفات الكيانات ، ويختار أيضًا من معلومات قاعدة البيانات الموجودة عليه ويشكل صفحة بها نتائج نتائج البحث.
في الوقت الذي بدأ فيه حل مشكلة البحث الغامض ، كان المخطط العام لهندسة البحث في المشروع كما يلي:

اختيار التكنولوجيا
كانت مهمتنا هي تخمين طلب المستخدم ، والذي قد يحتوي على أخطاء مطبعية. للقيام بذلك ، نحتاج إلى تحليل كل كلمة في الطلب وتحديد ما إذا كان المستخدم قد كتبها بشكل صحيح أم لا. في حالة وجود خطأ ، يجب تحديد الخيارات الأكثر ملاءمة. تحديد الإملاء الصحيح للكلمات أمر مستحيل بدون قاعدة بيانات الكلمات وأشكال كلمات اللغة التي نريد تخمينها. وببساطة ، يمكن تسمية قاعدة البيانات هذه بقاموس - هو الذي نحتاجه.
لتحديد خيارات الاستبدال للكلمات التي تم إدخالها مع وجود خطأ ، تم اختيار صيغة حساب المسافة Damerau - Levenshtein الشائعة. هذه الصيغة هي خوارزمية لمقارنة كلمتين. نتيجة المقارنة هي عدد العمليات لتحويل كلمة واحدة إلى أخرى. في البداية ، تتضمن مسافة Levenshtein استخدام 3 عمليات:
المسافة Damerau-Levenshtein هي نسخة موسعة من مسافة Levenshtein وتضيف عملية أخرى: تبديل ، أي التقليب من حرفين متجاورين.
وبالتالي ، يصبح عدد العمليات المستلمة عدد الأخطاء التي يرتكبها المستخدم عند كتابة الكلمة. لقد اخترنا حدود الخطأين ، نظرًا لأن العدد الأكبر لم يكن منطقيًا: في هذه الحالة ، لدينا خيارات كثيرة للغاية للاستبدال ، مما يزيد من احتمال حدوث خطأ.
للبحث عن أكثر ملاءمة لمتغيرات الكلمات المتشابهة في الصوت ، تم استخدام وظيفة الميتافون - هذه الوظيفة تحول الكلمة إلى شكلها الصوتي. لسوء الحظ ، لا يعمل الميتافون إلا مع حروف الأبجدية الإنجليزية ، لذا قبل حساب الشكل الصوتي ، نترجم الكلمة. يتم تخزين قيمة النموذج الصوتي في القاموس ، ويتم حسابها أيضًا في طلب المستخدم. تتم مقارنة القيم الناتجة بواسطة الدالة مسافة Damerau-Levenshtein.
يتم تخزين القاموس في قاعدة بيانات MySQL. من أجل عدم تحميل القاموس في ذاكرة التطبيق ، تقرر حساب المسافة Damerau-Levenshtein على الجانب الأساسي.
الدالة المعرفة من قبل المستخدم لحساب المسافة Damerau-Levenshtein ، المكتوبة على أساس
الدالة C التي كتبها Linus Torvalds ، قد استوفت بالكامل متطلباتنا. التي أنشأتها دييغو توريس.
بعد حساب مسافة Damerau-Levenshtein ، كان من الضروري فرز النتائج حسب درجة التشابه لتحديد الأكثر ملاءمة. للقيام بذلك ، استخدمنا خوارزمية أوليفر: حساب تشابه سطرين. في php ، يتم تمثيل هذه الخوارزمية بوظيفة similar_text. تقبل المعلمتان الأوليان للوظيفة خطوط الإدخال التي يجب مقارنتها ، ويعتبر ترتيب مقارنة السلسلة أمرًا مهمًا ، حيث أن الوظيفة تعطي قيمًا مختلفة بناءً على الترتيب الذي يتم به تمرير الخطوط إلى الوظيفة. يجب أن يتم تمرير المعلمة الثالثة المتغير الذي يتم وضع نتيجة المقارنة فيه. سيكون هذا رقمًا من 0 إلى 100 ، مما يعني نسبة التشابه بين الخطين. بعد الحساب ، يتم فرز النتائج بترتيب تنازلي من التشابه ، ثم يتم تحديد الخيارات مع أفضل القيم.
نظرًا لأن حساب مسافة Damerau-Levenshtein تم إجراؤه وفقًا لنسخ الكلمة ، فقد سقطت الكلمات ذات المعاني غير ذات الصلة بالكامل في النتائج. في هذا الصدد ، حددنا اختيار الخيارات مع نسبة تطابق تزيد عن 70٪.
أثناء عملية التطوير ، لاحظنا أن خوارزمية لدينا يمكنها تخمين الكلمات في تخطيطات مختلفة. لذلك ، كنا بحاجة إلى توسيع القاموس بإضافة معنى الكلمات في التخطيط العكسي. ظهرت متطلبات البحث تخطيطين فقط: الروسية والإنجليزية. قمنا بتكرار كل كلمة من استعلام بحث المستخدم في التخطيط العكسي وقمنا بمعالجة لحساب المسافة Damerau-Levenshtein. تتم معالجة خيارات التخطيط المباشر والعكس بشكل مستقل عن بعضها البعض ، ويتم تحديد الخيارات ذات أعلى نسبة تشابه. بالنسبة لخيارات التخطيط العكسي فقط ، ستكون القيمة في التخطيط المباشر هي قيمة استعلام البحث الذي تم تصحيحه.
خوارزمية البحث غامض
وبالتالي ، تم تشكيل خوارزمية الإجراءات من 6 خطوات رئيسية. أثناء الاختبار ، وجدنا أنه ليست كل الكلمات في طلبات المستخدم تحتاج إلى معالجة في شكلها الأصلي أو معالجتها بشكل عام. لحل مثل هذه الحالات ، تم تقديم خطوة إضافية ، أطلقنا عليها اسم محول أو مرشح. نتيجة لذلك ، تكونت الخوارزمية النهائية من 7 خطوات:
- تقسيم الاستعلام إلى كلمات منفصلة ؛
- تمرير كل كلمة من خلال المحول (حول هذا الموضوع) ؛
- لكل كلمة ، اجعل شكلها في تخطيط مختلف ؛
- يؤلف نسخة ؛
- قم بإجراء استعلام بحث في جدول القاموس ، ومقارنة كل إدخال من خلال المسافة Damerau-Levenshtein ؛
- اترك السجلات فقط بمسافة أقل من أو تساوي اثنين ؛
- من خلال خوارزمية أوليفر ، اترك الكلمات فقط مع نسبة تشابه تزيد عن 70٪
من الناحية التخطيطية ، تكون هذه الخوارزمية كما يلي:

تحويل كلمة وتصفية وظيفة
عندما بدأنا اختبار النموذج الأولي الأول دون محول ، أصبح من الواضح أنه لا توجد حاجة لمحاولة تخمين كل الكلمات في طلب المستخدم. تم إنشاء محول لهذه القيود. إنها تسمح لك بتحويل الكلمات إلى النموذج الذي نحتاجه وتصفية تلك الكلمات التي ، في رأينا ، لا تحتاج إلى التخمين.
في البداية ، تقرر أن يكون الحد الأدنى لطول الكلمة الذي يجب تمريره خلال الخوارزمية حرفين على الأقل. بعد كل شيء ، إذا دخل المستخدم ذريعة أو اتحاد من حرف واحد ، فإن احتمال التخمين هو الحد الأدنى عمليا. كانت الخطوة الثانية لتقسيم الاستعلام إلى كلمات. بادئ ذي بدء ، اخترنا مجموعة من الأحرف التي يمكن أن تحتوي على كلمات: أحرف وأرقام وفترة واصلة (شرطة). الفراغات والشخصيات الأخرى هي محددات للكلمات.
في كثير من الأحيان ، يقوم المستخدمون بإدخال الأرقام للإشارة إلى الحجم أو الكمية. في هذه الحالة ، سيكون من الخطأ تصحيح مثل هذا الطلب. على سبيل المثال ، أدخل المستخدم استعلام "الماء 1.1 لتر". إذا صحح طلبه بمقدار 1.5 أو 1.0 ، فسيكون ذلك خطأ. في مثل هذه الحالات ، قررنا تخطي الكلمات برقم. هم ، متجاوزين خوارزمية لدينا ، يتم نقلهم إلى بحث النص الكامل للأبو الهول.
يرتبط تحويل آخر بالنقاط في أسماء العلامات التجارية - على سبيل المثال: Dr. Pepper أو Mr.Proper. في الحالات التي يوجد فيها رمز نقطة في منتصف الكلمة ، فإننا نقسمها إلى قسمين ، ونضيف مسافة. الحالة الثانية مع نقطة في منتصف الكلمة - هنا نتذكر علامات الاختصار. على سبيل المثال ، ماركة ROCS - في هذه الحالة ، قمنا بقطع النقاط والحصول على كلمة واحدة. يعمل هذا التحويل إذا كان هناك حرف واحد فقط بين النقاط.
في الحالات التي يكون فيها الواصلة (شرطة) موجودة في الكلمة ، يجب تقسيم الكلمة إلى عدة ومحاولة تخمينها بشكل فردي ، ثم لصق أفضل الخيارات معًا.
نتيجة لذلك ، تم تطوير محول للحصول على أكثر دقة التعرف على الطلب - تم تنفيذ معظم العمل على إعداد جميع الوظائف من خلال هذا التطور بالذات. بفضله إلى حد كبير ، يتم إجراء ضبط وضبط البحث الضبابي بأكمله. كرر باختصار القواعد التي يتم بها إجراء الفرز وتحويل الكلمات:
- يجب أن تكون الكلمة أطول من حرفين
- يجب أن تحتوي الكلمة على أحرف فقط وحرف فترة ووصلة (شرطة)
- إذا كانت النقطة في منتصف الكلمة ، تتم إضافة مسافة بعدها
- إذا كان الاختصار ، يتم قطع النقاط ويتم لصق الحروف معًا
- لا تحاول تخمين الكلمة إذا كان هناك رقم فيها
- إذا كانت الكلمة تحتوي على واصلة (شرطة) ، فاقسمها إلى عدة ، ابحث بشكل منفصل والغراء في النهاية
تجميع القاموس
كما ذكرنا سابقًا ، من أجل تصحيح طلب المستخدم ، من الضروري تحديد الكلمات التي تم كتابتها بشكل غير صحيح وأيها غير صحيحة. لهذا ، تم إنشاء قاموس في النظام حيث يجب تضمين الكلمات ذات الهجاء الصحيح.
في المرحلة الأولى ، نشأت مسألة ملء القاموس - كنتيجة لذلك ، قررنا استخدام محتوى الكتالوج لتجميعه. نظرًا لاستيراد المعلومات المتعلقة بالبضائع من وقت لآخر من نظام خارجي وفهرستها لنظام البحث عن النص الكامل لـ Sphinx ، فقد تقرر إضافة وظيفة تجميع القاموس في هذه المرحلة. اتبعنا المنطق التالي: إذا لم تكن الكلمة في محتوى البضاعة ، فلماذا نحاول تخمينها؟
تم دمج معلومات المنتج في نص شائع وتم إجراؤها عبر محول. تم تعديل وضع تشغيل المحول قليلاً: عند اختراق الكلمات خلال واصلة (شرطة) ، تم حفظ كل جزء من الأجزاء في القاموس بشكل منفصل ، وعند استبدال نقاط في القاموس ، تتم إضافة البيانات الأصلية والمتغيرة. وبما أنه عند مقارنة الكلمات لحساب مسافة Damerau-Levenshtein ، يتم استخدام نسخ الكلمة ، بالإضافة إلى القاموس ، يتم إضافة النسخ.
كان هناك الكثير من الأخطاء المطبعية في محتوى البضاعة ، ولهذا الغرض وضعت علامة في القاموس ، وخلال تركيبها والتي لم تعد تستخدم الكلمة في البحث. يسمح المحتوى من 35 ألف منتج لإنشاء قاموس من 100 ألف كلمة فريدة ، والتي في النهاية لم تكن كافية لبعض استفسارات المستخدم. في هذا الصدد ، كان من الضروري توفير وظيفة التحميل لتخصيبها. تم إنشاء أمر وحدة التحكم لتحميل القواميس. يجب أن يتوافق تنسيق الملفات مع بيانات القواميس مع ملف CSV. يحتوي كل إدخال على حقل واحد فقط مع حقل القاموس نفسه. لتمييز البيانات التي تم تنزيلها عن البيانات التي تم إنشاؤها بناءً على محتوى البضائع ، تمت إضافة علامة خاصة.
نتيجة لذلك ، يحتوي جدول القاموس على المخطط التالي:
اسم الحقل | نوع الحقل |
---|
الكلمة | سلسلة |
النسخ | سلسلة |
أضيفت يدويا | منطقي |
لا تستخدم | منطقي |
قبل تطوير وظيفة البحث الغامض ، كانت هناك حقول في المنتجات تحتوي على مجموعة من الكلمات مع الأخطاء المطبعية. في الجولة الأولى من توليد القاموس ، وصلوا إلى محتواها. نتيجةً لذلك ، تم الحصول على قاموس يحتوي على أخطاء مطبعية ، وكان محتواها غير مناسب للعمل بشكل صحيح. لذلك ، تمت إضافة أمر وحدة تحكم آخر له وظيفة إنشاء القاموس العكسي. باستخدام محتوى حقل معيّن من البضائع ، بحث الفريق عن الكلمات الموجودة في القاموس وحذفها من القاموس. بعد التنظيف ، تم استبعاد هذه الحقول من الفهرسة.
التكامل Bitrix
لتنفيذ الحد الأدنى المطلوب من الوظائف ، تم إنشاء ثلاث فئات:
- DictionaryTable - أنظمة Bitrix ORM للعمل مع القاموس
- قاموس - فئة جيل القاموس
- البحث - فئة تنفيذ البحث
للتكامل في Bitrix ، كان مطلوبًا إجراء تغييرات على مكونين:
- bitrix: search.page
- bitrix.search.title
قبل تنفيذ الطلب ، يتم استدعاء طريقة المعالجة لاكتشاف الأخطاء وتحديد الخيارات المناسبة:

لتجميع قاموس ، تم تسجيل حدث للفهرسة بواسطة وحدة البحث لعناصر كتلة المعلومات مع البضائع (البحث: BeforeIndex).


الخطط المستقبلية
هذا النهج ليس مثاليًا من حيث الأداء. مع زيادة حجم القاموس إلى 1M + الكلمات ، يمكن أن يزيد وقت استجابة قاعدة البيانات بشكل كبير. على الرغم من أن القاموس صغير ، إلا أن الأداء يناسبنا. قد يكون من الضروري تطبيق الخوارزمية في المستقبل من خلال محرك ليفينشتاين الآلي أو شجرة بادئة.
الخاتمة
لذلك ، لا يدخر أي محرك بحث ظهور طلبات البحث التي تنتهك قواعد التدقيق الإملائي المقبولة عمومًا - سواء أكانت خطأً إملائيًا عشوائيًا أو نقصًا حقيقيًا في إملاء الكلمات. لذلك ، حتى من دون اللجوء إلى خيارات البحث المبهم الكلاسيكية ، Google أو Yandex ، يمكنك إنشاء خياراتك الخاصة ، وذلك بفضل كلٍ من المستخدم ومالك الموقع سوف يكونا قادرين على الحصول على النتيجة المرجوة.
يمكن الاطلاع على رمز
تنفيذنا في المستودع:
github.com/qsoft-dev/damlev-bitrix