كيف يمكنك جعل عمليات البحث عن النص الكامل لأحرف البدل الرائدة تعمل في SQL Server؟

StackOverflow https://stackoverflow.com/questions/3400

  •  08-06-2019
  •  | 
  •  

سؤال

ملحوظة: أنا أكون باستخدام إمكانات البحث عن النص الكامل لـ SQL، وعبارات CONTAINS وكل شيء - فإن * هو حرف البدل في النص الكامل، و% مخصص لعبارات LIKE فقط.

لقد قرأت في عدة أماكن الآن أن عمليات البحث عن "أحرف البدل الرائدة" (على سبيل المثال:استخدام "*overflow" لمطابقة "stackoverflow") غير مدعوم في MS SQL.أفكر في استخدام أ وظيفة CLR لإضافة مطابقة regex, ، لكني أشعر بالفضول لمعرفة الحلول الأخرى التي قد يكون لدى الأشخاص.

مزيد من المعلومات: يمكنك إضافة العلامة النجمية فقط في نهاية الكلمة أو العبارة. - إلى جانب تجربتي التجريبية:عند مطابقة "myvalue"، تعمل "my*"، لكن "(القيمة النجمية)" لا تُرجع أي تطابق، عند إجراء استعلام بسيط مثل:

SELECT * FROM TABLENAME WHERE CONTAINS(TextColumn, '"*searchterm"');

وبالتالي، حاجتي إلى الحل البديل.أنا أستخدم البحث في موقعي فقط على صفحة بحث فعلية - لذلك يجب أن يعمل بشكل أساسي بنفس الطريقة التي يعمل بها Google (في نظر مستخدم من نوع Joe Sixpack).ليست معقدة إلى هذا الحد، لكن هذا النوع من المباريات لا ينبغي أن يفشل حقًا.

لا يوجد حل صحيح

نصائح أخرى

الحل البديل لأحرف البدل البادئة فقط:

  • قم بتخزين النص المعكوس في حقل مختلف (أو في عرض مادي)
  • إنشاء فهرس نص كامل في هذا العمود
  • ابحث عن النص المعكوس بعلامة *

    SELECT * 
    FROM TABLENAME 
    WHERE CONTAINS(TextColumnREV, '"mrethcraes*"');
    

بالطبع هناك عيوب كثيرة، فقط للحل السريع ...

ناهيك عن الاحتواء ...

مشكلة أحرف البدل الرائدة:لا يمكن فهرستها، وبالتالي فأنت تقوم بإجراء فحص كامل للجدول.

من الممكن استخدام حرف البدل "*" في نهاية الكلمة أو العبارة (البحث عن البادئة).

على سبيل المثال، سيجد هذا الاستعلام جميع "قاعدة البيانات"، "قاعدة البيانات"، "قواعد البيانات" ...

SELECT * FROM SomeTable WHERE CONTAINS(ColumnName, '"datab*"')

ولكن، لسوء الحظ، ليس من الممكن البحث باستخدام أحرف البدل الرائدة.

على سبيل المثال، لن يجد هذا الاستعلام "قاعدة بيانات"

SELECT * FROM SomeTable WHERE CONTAINS(ColumnName, '"*abase"')

ربما لإضافة المزيد من الوضوح إلى هذا الموضوع، من الاختبار الذي أجريته على 2008 R2، فإن Franjo صحيح أعلاه.عند التعامل مع البحث عن النص الكامل، على الأقل عند استخدام العبارة CONTAINS، لا يمكنك استخدام مسافة بادئة , ، زائدة فقط وظيفيا.* هو حرف البدل، وليس % في النص الكامل.

اقترح البعض أنه تم تجاهل *.لا يبدو أن هذا هو الحال، يبدو أن نتائجي تظهر أن وظيفة زائدة * تعمل.أعتقد أن المحرك يتجاهل البادئة *.

لكن مشكلتي الإضافية هي أن نفس الاستعلام، مع زائدة *، الذي يستخدم النص الكامل مع أحرف البدل، عمل بسرعة نسبيًا في 2005 (20 ثانية)، وتباطأ إلى 12 دقيقة بعد ترحيل قاعدة البيانات إلى 2008 R2.يبدو أن مستخدمًا واحدًا آخر على الأقل حصل على نتائج مماثلة وبدأ مشاركة في المنتدى أضفتها إلى...لا يزال FREETEXT يعمل بسرعة، ولكن "يبدو" أن شيئًا ما قد تغير مع الطريقة التي يعالج بها 2008 التتبع * في CONTAINS.إنهم يقدمون جميع أنواع التحذيرات في Upgrade Advisor بأنهم "حسّنوا" النص الكامل بحيث قد يتعطل الكود الخاص بك، لكنهم للأسف لا يعطونك أي تحذيرات محددة حول بعض التعليمات البرمجية المهملة وما إلى ذلك....مجرد إخلاء للمسؤولية بأنهم قاموا بتغييره، استخدمه على مسؤوليتك الخاصة.

http://social.msdn.microsoft.com/Forums/ar-SA/sqlsearch/thread/7e45b7e4-2061-4c89-af68-febd668f346c

ربما تكون هذه هي أقرب نتيجة لمرض التصلب العصبي المتعدد تتعلق بهذه المشكلات ... http://msdn.microsoft.com/en-us/library/ms143709.aspx

هناك شيء واحد يستحق الأخذ في الاعتبار وهو أن استعلامات أحرف البدل الرائدة تأتي بأداء متميز مقارنة باستخدامات أحرف البدل الأخرى.

حرف البدل في SQL Server هو % التوقيع ويعمل بشكل جيد، الرائدة، زائدة أو غير ذلك.

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

من كتب SQL Server عبر الإنترنت:

لكتابة استعلامات النص الكامل في Microsoft SQL Server 2005 ، يجب أن تتعلم كيفية استخدام FREETEXT TRANDSACT-SQL ، ووظائف Rowset ذات القيمة المتقابلة FREETSTABLE و FREETEXTTABLE.

وهذا يعني أن كافة الاستعلامات المكتوبة أعلاه مع % و_ ليست استعلامات نصية كاملة صالحة.

فيما يلي نموذج لما يبدو عليه الاستعلام عند استدعاء الدالة CONTAINSTABLE.

حدد الترتيب ، *من Tablename ، يحتوي على (tablename ، *، "" *wildcard "') searchable حيث [key] = tablename.pk order by searchtable.rank desc

لكي تعرف الدالة CONTAINSTABLE أنني أستخدم بحث بدل، يجب أن أضعه بين علامتي اقتباس مزدوجتين.يمكنني استخدام حرف البدل * في البداية أو النهاية.هناك الكثير من الأشياء الأخرى التي يمكنك القيام بها عند إنشاء سلسلة البحث للدالة CONTAINSTABLE.يمكنك البحث عن كلمة بالقرب من كلمة أخرى، والبحث عن الكلمات التصريفية (محرك = محركات، قاد، يقود، ويقود)، والبحث عن مرادف لكلمة أخرى (يمكن أن يكون للمعدن مرادفات مثل الألومنيوم والفولاذ).

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

[تحديث]

أرى أنك قمت بتحديث سؤالك وأعلم أنك بحاجة إلى استخدام إحدى الوظائف.

لا يزال بإمكانك البحث باستخدام حرف البدل في البداية، ولكن إذا لم تكن الكلمة كلمة كاملة تتبع حرف البدل، فيجب عليك إضافة حرف بدل آخر في النهاية.

Example:  "*ildcar" will look for a single word as long as it ends with "ildcar".

Example:  "*ildcar*" will look for a single word with "ildcar" in the middle, which means it will match "wildcard".  [Just noticed that Markdown removed the wildcard characters from the beginning and ending of my quoted string here.]

[التحديث رقم 2]

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

لمعلوماتك فقط، لا تقوم Google بأي عمليات بحث أو اقتطاع للسلاسل الفرعية، يمينًا أو يسارًا.لديهم حرف بدل * للعثور على كلمات غير معروفة في العبارة، ولكن ليس كلمة واحدة.

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

كمعلمة في الإجراء المخزن يمكنك استخدامها على النحو التالي:

ALTER procedure [dbo].[uspLkp_DrugProductSelectAllByName]
(
    @PROPRIETARY_NAME varchar(10)
)
as
    set nocount on
    declare @PROPRIETARY_NAME2 varchar(10) = '"' + @PROPRIETARY_NAME + '*"'

    select ldp.*, lkp.DRUG_PKG_ID
    from Lkp_DrugProduct ldp
    left outer join Lkp_DrugPackage lkp on ldp.DRUG_PROD_ID = lkp.DRUG_PROD_ID
    where contains(ldp.PROPRIETARY_NAME, @PROPRIETARY_NAME2)

عندما يتعلق الأمر بالبحث عن النص الكامل، لا شيء يتفوق على أموالي لوسين.هناك .منفذ صافي متاح متوافق مع الفهارس التي تم إنشاؤها باستخدام إصدار Java.

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

كمثال، وظيفة البحث هذه مدعوم من Lucene.Net.

ربما يقدم الرابط التالي الإجابة النهائية على هذا الاستخدام لأحرف البدل: إجراء عمليات بحث FTS Wildcard.

لاحظ المقطع الذي يقول:"ومع ذلك، إذا قمت بتحديد"سلسلة" أو "الفصلعين"، فلن تحصل على النتيجة المتوقعة.سيتم اعتبار العلامة النجمية علامة ترقيم عادية وليست حرف بدل."

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

    pie
    applepie
    spies
    cherrypie
    dog
    cat

لمطابقة جميع الكلمات التي تحتوي على "فطيرة" في قاعدة البيانات هذه في جدول fts "full_text" مع الحقل "text":

    to-match <- SELECT word FROM words WHERE word LIKE '%pie%'
    matcher = ""
    a = ""
    foreach(m, to-match) {
      matcher += a
      matcher += m
      a = " OR "
    }
    SELECT text FROM full_text WHERE text MATCH matcher

٪ يطابق أي عدد من الأحرف _ يطابق حرف واحد

لم أستخدم مطلقًا فهرسة النص الكامل ولكن يمكنك إنجاز استعلامات بحث معقدة وسريعة إلى حد ما بمجرد استخدام وظائف سلسلة T-SQL المضمنة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top