الستیک سرچ – بخش دوم: انواع کوئریهای کاربردی
در بخش اول این سری درباره پایههای کوئرینویسی در Elasticsearch صحبت کردم: مدل ذهنی، چرا mapping بهترین دوست شماست و اینکه چه موقع باید از فیلتر استفاده کرد و چه موقع از match. حالا وقتشه وارد جزئیات بشیم و سراغ انواع کوئریهای کاربردی بریم که توی پروژههای واقعی بیشترین استفاده رو دارند.
اگر بخش اول بیشتر درباره چطور مثل Elasticsearch فکر کنیم بود، این بخش درباره چطور به زبان اون حرف بزنیم هست.
کوئری match_phrase
یکی از اشتباهات رایج اینه که فکر میکنیم match
ترتیب کلمات رو رعایت میکنه. ولی اینطور نیست.
مثال:
match: "مهندس یادگیری ماشین"
میتونه نتایجی مثل این برگردونه:- «مسیرهای یادگیری برای مهندسان طراحی ماشین»
- «مهندسانی که روی الگوریتمهای یادگیری برای ماشینها کار میکنند»
ولی اگه کاربر دنبال عنوان شغلی دقیق باشه، انتظار داره همون عبارت رو پیدا کنه. اینجاست که match_phrase
وارد عمل میشه:
{ "query": { "match_phrase": { "title": "مهندس یادگیری ماشین" } } }
این کوئری مطمئن میشه فقط نتایجی بیاد که «مهندس یادگیری ماشین» دقیقاً پشت سر هم اومده باشه.
کوئری بازهای (Range) – اعداد، قیمت، متریکها
Elasticsearch فقط برای متن نیست. کوئریهای Range اجازه میدن روی فیلدهای عددی، قیمت، امتیاز یا حتی متریکهای لاگ فیلتر بزنیم.
فرض کنید توی فروشگاه آنلاین میخواید محصولات بین ۱۰۰ تا ۵۰۰ هزار تومن رو نشون بدید:
{ "query": { "range": { "price": { "gte": 100000, "lte": 500000 } } } }
نکته: Range فقط برای قیمت یا عدد نیست. برای تاریخ و متریکها هم عالیه. مثلاً:
- لاگهای ۲۴ ساعت گذشته.
- محصولاتی با امتیاز بالای ۴.۵.
- کارمندانی با سابقه بین ۳ تا ۷ سال.
به عنوان مثال برای استخراج یک زمان نسبی:
{ "query": { "range": { "timestamp": { "gte": "now-24h" } } } }
کوئری پیشوندی و وایلدکارت (Prefix & Wildcard)
گاهی کاربر کلیدواژه رو کامل یادش نیست. با Prefix میشه دنبال رشتهای گشت که ابتدای کلمه باشه:
{ "query": { "prefix": { "username": "sha" } } }
این میتونه shayan
، shahrzad
یا shahram
رو پیدا کنه. وایلدکارت حتی انعطاف بیشتری داره:
{ "query": { "wildcard": { "username": "sha*" } } }
توجه: این نوع کوئریها سنگینن و میتونن سرعت رو بیارن پایین، چون باید کلی اصطلاح رو بررسی کنن. بهتره فقط برای autocomplete استفاده بشن یا از edge n-gram توی زمان ایندکسگذاری استفاده کنید.
کوئری چند-فیلدی (Multi-Match)
فرض کنید کسی دنبال “Shayan” میگرده و میخواید هم توی فیلد name
و هم username
سرچ بشه. به جای نوشتن دو کوئری، میتونید از multi_match
استفاده کنید:
{ "query": { "multi_match": { "query": "Shayan", "fields": ["name", "username"] } } }
این نوع کوئری مخصوصاً برای سرچبارهایی که روی چند فیلد مختلف کار میکنن خیلی کاربردیه.
کوئری وجود فیلد (Exists)
برای بررسی وجود یا عدم وجود یک فیلد استفاده میشه
مثلاً:
- فیلتر کردن کاربرانی که ایمیل دارن.
- پیدا کردن محصولاتی که هنوز تخفیف براشون ست نشده.
{ "query": { "exists": { "field": "email" } } }
اگه با must_not
ترکیبش کنید، کاربرانی که ایمیل ندارن رو پیدا میکنید.
کوئری شناسهها (IDs)
یکی از سریعترین و underrated ترین کوئریها همین ids
هست.
وقتی شناسهی داکیومنتها رو از قبل دارید (مثلاً از یک سیستم پیشنهاددهنده یا سرویس خارجی)، میتونید خیلی سریع بیاریدشون:
{ "query": { "ids": { "values": ["1", "2", "3"] } } }
برای سناریوهای ترکیبی (مثلاً اتصال Elasticsearch با مدلهای یادگیری ماشین) خیلی به درد میخوره.
جمعبندی
این کوئریها—phrase، range، prefix/wildcard، multi-match، exists و ids—جعبهابزار اصلی هر کسی هستن که جدی با Elasticsearch کار میکنه.
کاربردهای واقعی؟
- موتور جستجوی شغلی.
- فیلتر محصولات فروشگاه آنلاین.
- هندل کردن ورودیهای ناقص کاربران.
- ساختن سیستمهای ترکیبی هوش مصنوعی + جستجو.
در بخش بعدی این سری میریم سراغ aggregation و scoring: جایی که Elasticsearch نه فقط داکیومنتها رو پیدا میکنه، بلکه رتبهبندی و خلاصهسازی هم انجام میده.
تا اون موقع، این کوئریها رو روی پروژههاتون تست کنید. خیلی زود میبینید که جستجو فقط پیدا کردن نیست—بلکه فهمیدن نیت واقعی کاربره.