جستجوی Full Text به روش Natural Language در MySQL

در این مطلب می‌خواهیم در مورد نحوه استفاده از متد Natural language full text search در پایگاه داده MySQL صحبت کنیم. استفاده از این متد بسیار ساده است. برای اینکار به دستورات Match و Against نیاز داریم.

در متد جستجوی Natural language در MySQL به دنبال ردیف‌ها یا اسنادی می‌گردیم که از نظر زبان طبیعی با عبارت جستجو شده ارتباط داشته باشند. ارتباط به کمک یک عدد اعشاری مثبت مقداردهی می‌شود. یعنی اگر برای ردیف یا سندی، عدد Relevance یا همان مرتبط بودن، مقدار صفر باشد، میان آن سند با عبارت جستجو شده شباهتی وجود ندارد. پایگاه داده MySQL برای محاسبه شباهت، از فاکتورهای متنوعی استفاده می‌کند که برخی از آنها شامل این موارد است: تعداد کلمات در سند(ردیف)، تعداد کلمات یکتا در سند(ردیف)، تعداد کل کلمات در کالکشن، و تعداد اسنادی که شامل کلمه‌ای خاص هستند.

همانطور که در ابتدای این پست هم اشاره شد، برای اجرای جستجوی Natural Language در MySQL به دو تابع Match و Against نیاز داریم. تابع Match تعیین کننده ستونی است که جستجو بر روی محتوای آن صورت می‌گیرد و تابع Against  نیز تعیین کننده عبارت مورد نیاز ماست. برای ادامه ما یک جدول فرضی به نام products میسازیم که شامل ستون‌های زیر است:

همچنین یک سری رکورد اطلاعاتی پیشفرض نیز آماده کرده‌ایم که از لینک زیر قابل دریافت است. اگر این فایل را در داخل پایگاه‌داده خود Import کنید، رکوردهای نمونه به جدول اضافه خواهد شد و به کمک این اطلاعات، می‌توانیم مثال‌های این آموزش را بصورت عملی اجرا کنیم.

[button color=”green” size=”medium” link=”https://myempire.ir/wp-content/uploads/mysqlsampledatabase.zip” target=”blank” ]دریافت پایگاه‌داده نمونه[/button]

همچنین لازم است تا بر روی جدول فوق قابلیت Full text search را فعال کنیم. قبلا در مطلبی با عنوان آشنایی با full text search در MySQL نحوه فعال کردن این قابلیت را شرح دادیم، اما بطور خلاصه، به کمک دستورات SQL زیر، این قابلیت فعال خواهد شد:


ALTER TABLE products
ADD FULLTEXT(productline);

در گام دوم، باید Query لازم برای جستجو را بنویسیم و این Query را بر روی پایگاه‌داده اجرا کنیم. میخواهیم محصولاتی که در ستون productLine آنها عبارت Classic وجود دارد را واکشی کنیم. برای این کار می‌توانیم از Query زیر استفاده کنیم.


SELECT productName, productline
FROM products
WHERE MATCH(productline) AGAINST('Classic');

همانطور که مشاهده می‌کنید، این دستور ساختاری کاملا مشابه با Query های عادی دارد. تنها تفاوت موجود، استفاده از دو تابع Match و Against است. به جدول جواب نگاه کنید:

شاید تا به اینجای کار به نظر برسد که جستجوی full text با دستور Like نیز قابل پیاده‌سازی است، پس چرا این همه تلاش کردیم تا از Full text search استفاده کنیم؟

پاسخ این است که نباید زود قضاوت کرد. شاید شروع به کار با این قابلیت مشابه دستورات Like باشد اما هر چه پیش برویم، تفاوت‌ها را بیشتر مشاهده خواهید کرد. برای ادامه می‌خواهیم جستجوی خود را کمی پیچیده‌تر کنیم. فرض کنید میخواهیم محصولاتی را واکشی کنیم که در آنها عبارت Classic یا Vintage موجود باشد. برای اینکار می‌توانیم از دستور زیر استفاده کنیم:


SELECT productName, productline
FROM products
WHERE MATCH(productline) AGAINST('Classic,Vintage');

تابع Against در حالت پیشفرض از مد NATURAL LANGUAGE  استفاده می‌کند. علاوه بر این مد، می‌توانیم از مد Boolean هم استفاده کنیم که جزئیات بیشتری را در اختیار ما قرار می‌دهد. درباره این مد، بعدا بطور مفصل صحبت خواهیم کرد.

نکته مهم دیگر این است که MySQL به طور پیشفرض جستجو را در حالت Case-Insensitive انجام می‌دهد. اگر حساس بودن به حروف بزرگ و کوچک برای شما اهمیت دارد، باید Collation ستون‌های index خود را بر روی مقادیر Binary قرار دهید.

[divider]

مرتب سازی نتایج جستجو بر اساس مرتبط بودن

در این بخش مثالی از نحوه مرتب‌سازی نتایج جستجو بر اساس میزان مرتبط بودن نتایج را مورد بررسی قرار می‌دهیم.

مانند مثال قبل، جدول products را میسازیم و این بار قابلیت Full text search را بر روی ستون productName فعال می‌کنیم:


ALTER TABLE products
ADD FULLTEXT(productName);

در گام دوم باید Query جستجو را بسازیم. می‌خواهیم محصولاتی که شامل عبارت ۱۹۳۲ و Ford هستند را واکشی کنیم:

SELECT productName, productline
FROM products
WHERE MATCH(productName) AGAINST('1932,Ford')

حال به جدول جواب دقت کنید:

اگر به جدول جواب توجه کنید، خواهید دید که ابتدا، الویت با محصولاتی است که شامل هر دو عبارت هستند، سپس محصولاتی که کلمه اول در تابع Against را دارا هستند در الویت قرار دارند و در نهایت محصولاتی که کلمه دوم در تابع Against را دارا هستند در نتیجه ظاهر شده‌اند. حتما تجربه کارکردن با موتورهای جستجو را دارید، به وضوح درک می‌کنید که وقتی دنبال یک عبارت می‌گردید، کلماتی که در ابتدای عبارت هستند اهمیت بیشتری دارند. با همین فرض ساده می‌توانیم موتور جستجوی خود را بسازیم. تنها کافیست تا عبارت مورد نیاز را از کاربر دریافت کنیم، آن را به کلمات جدا از هم تجزیه کنیم، حروف ربط مانند “از،در،با،برای،به،تا و…”  را از لیست کلمات بدست آمده حذف کنیم و با کلمات باقی مانده، جستجو را بر روی پایگاه‌داده‌ها انجام دهیم.

البته در مورد گوگل اوضاع کمی متفاوت است. الگوریتم پشت پرده‌ی این موتور جستجو برای ما آشکار نیست اما تا جایی که می‌شود از شواهد موجود گمانه زنی کرد، وقتی گوگل عبارتی را از کاربر می‌گیرد، آن را تحلیل کرده و کلمات کلیدی آن را استخراج می‌کند و سپس ترتیب کلمات را بر اساس اهمیت آنها در جمله قرار می‌دهد و با لیست کلمات موجود جستجو را انجام می‌دهد. البته این فقط یک گمانه‌زنی است، روی آن حساب نکنید!

در انتها بهتر است بدانید که در هنگام استفاده از قابلیت جستجو در MySQL دو نکته را باید در نظر گرفت:

  • اولین نکته این است که حداقل طول کلمه برای جستجو باید ۴ کاراکتر باشد. یعنی MySQL برای کلماتی که کمتر از ۴ کاراکتر هستند، مانند car,cat و… نتیجه‌ای را ایجاد نخواهد کرد.
  • مورد دوم این است که MySQL در جستجوی Full text نسبت به یک سری کلمات رزرو شده که اصطلاحا آنها را Stop words می‌نامد نیز مقاوم است و برای این کلمات نیز نتیجه‌ای را ایجاد نخواهد کرد. این لیست را می‌توان در مستندات MySQL پیدا کرد.

[button color=”blue” size=”medium” link=”https://dev.mysql.com/doc/refman/8.0/en/fulltext-stopwords.html” target=”blank” ]لیست Stop Word های MySQL[/button]

موفق و پیروز باشید…

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *