جستجوی متنی در Laravel با MongoDB Search
خلاصهٔ کاملتر
وقتی توی یه اپ میخوای قابلیت جستجو پیاده کنی، اولین چیزی که به ذهن میرسه شاید یه LIKE ساده یا regex باشه. ولی این روشها مشکل دارن: regex معمولاً یه full index scan انجام میده و با بزرگتر شدن دیتاست، کندتر میشه. حتی ایندکس متنی قدیمی MongoDB (یعنی $text) هم فقط یه الگوریتم ابتدایی Term Frequency داره و نتایج رو بر اساس ربط واقعی مرتب نمیکنه.
MongoDB Search که روی موتور Lucene ساخته شده، این مشکل رو حل میکنه. Lucene همون موتوری هست که پایه خیلی از موتورهای جستجوی بزرگ رو تشکیل میده. این قابلیت از سپتامبر ۲۰۲۵ علاوه بر Atlas، توی نسخه Community رایگان MongoDB هم در دسترسه و نیازی به سرویس جداگانه یا API جدید نیست — همون connection معمولی MongoDB کافیه.
مزیتهای کلیدی MongoDB Search نسبت به روشهای قدیمی:
- Fuzzy matching با الگوریتم Levenshtein Distance: حتی اگه کاربر غلط تایپ کنه، نتیجه درست پیدا میشه.
- الگوریتم BM25 برای scoring دقیقتر و ربطپذیری بهتر.
- پشتیبانی از زبانهای مختلف در tokenization.
- Autocomplete برای پیشنهاد نتایج در لحظه تایپ.
برای استفاده از این قابلیت توی Laravel، اول باید یه Search Index بسازی. این ایندکس «اینورتد ایندکس» هست — یعنی بهجای اینکه روی سند ایندکس بذاره، روی توکنهای متنی ایندکس میسازه. در کد زیر با dynamic: false مشخص میکنیم فقط فیلدهای انتخابی ایندکس بشن:
$searchFields = ['title', 'plot', 'fullplot', 'cast', 'directors'];
$fieldMappings = [];
foreach ($searchFields as $field) {
$fieldMappings[$field] = ['type' => 'string'];
}
$result = $collection->createSearchIndex(
['mappings' => ['dynamic' => false, 'fields' => $fieldMappings]],
['name' => $indexName]
);بعد از ساخت ایندکس، میشه با aggregation pipeline توی Laravel Eloquent جستجو کرد. در کوئری زیر، از $meta: searchScore استفاده شده تا امتیاز ربطپذیری هر نتیجه هم برگردونده بشه — این امتیاز کمک میکنه بفهمی موتور جستجو هر نتیجه رو چقدر مرتبط میدونه:
$results = Movie::query()
->aggregate()
->search(
operator: Search::text(
path: ['title', 'plot', 'fullplot', 'cast', 'directors'],
query: $query
),
index: config('fulltext.index.name')
)
->addFields(score: ['$meta' => 'searchScore'])
->limit(config('fulltext.search.limit'))
->get();پروژه از دیتابیس نمونه sample_mflix که توی MongoDB Atlas قابل بارگذاریه استفاده میکنه و شامل یه کالکشن فیلمها با فیلدهایی مثل عنوان، خلاصه داستان، بازیگران و کارگردانهاست. برای راهاندازی سریعتر، یه محیط آماده روی GitHub Codespaces هم وجود داره که نیازی به نصب PHP و Laravel به صورت دستی نداره.
نکات کلیدی:
- MongoDB Search مبتنی بر Lucene هست و توی MongoDB Community (از سپتامبر ۲۰۲۵) و Atlas در دسترسه.
- جستجوی متنی واقعی باید نتایج رو بر اساس ربطپذیری مرتب کنه، نه تاریخ یا معیارهای دیگه.
- روشهای قدیمی مثل LIKE، regex و حتی $text ایندکس برای جستجوی مقیاسپذیر کافی نیستن.
- Search Index با createSearchIndex ساخته میشه و از aggregation pipeline برای کوئری استفاده میشه.
- امتیاز searchScore کمک میکنه ربطپذیری نتایج رو اندازهگیری و تنظیم کنی.




