یک تیم توسعهدهنده OpenSearch را با SQLite FTS5 ترکیب کرد و نرخ جستجوهای ویدئویی بدون نتیجه را از ۱۱.۴ درصد به ۲.۱ درصد کاهش داد، در حالی که تأخیر (latency) را زیر ۲۰ میلیثانیه نگه داشت. اکنون کاربرانی که عبارت “blackpink jenny solo stag” را تایپ میکنند، به جای یک لیست خالی، نتیجه صحیح یعنی “BLACKPINK Jennie SOLO stage” را مشاهده میکنند.
چرا این تغییر لازم بود
گزارشهای جستجو در یک پلتفرم میزبانی ویدئو نشاندهنده یک مشکل تکراری بود: یک غلط تایپی ساده در عنوانی که با حروف لاتین نوشته شده بود، میتوانست تمام نتایج مطابقت را از بین ببرد. افزونه FTS5 در SQLite که به دلیل تواناییاش در تطبیق زیررشتهها (substrings) در متون چینی، ژاپنی و کرهای (CJK) بسیار ارزشمند است، قابلیت جستجوی فازی (fuzzy matching) را ندارد. یک کاراکتر اشتباه در نام یا عنوان آهنگ، کل پرسوجو (query) را مختل میکند.
خط لوله (pipeline) موجود، SQLite را به عنوان تنها ایندکس در نظر میگرفت. این سیستم پرسوجوهای CJK را به خوبی مدیریت میکرد، اما هیچ لایه حفاظتی برای غلطهای تایپی در حروف لاتین نداشت. بنابراین، تیم به دنبال یک موتور جستجوی مکمل گشت که بتواند بدون حذف لایه اثباتشده FTS5، قابلیت تحمل غلطهای تایپی (typo tolerance) را فراهم کند.
نحوه اضافه شدن OpenSearch
OpenSearch به عنوان سرویس جستجوی خط مقدم عمل میکند؛ در حالی که SQLite همچنان منبع اصلی دادهها (source of truth) باقی میماند. این دو سیستم به صورت موازی اجرا میشوند: ابتدا پرسوجوی کاربر توسط OpenSearch دریافت میشود و اگر پاسخ آن به اندازه کافی سریع باشد، نتایج آن نمایش داده میشود. اگر OpenSearch با خطا مواجه شود یا زمان پاسخگویی آن تمام شود (timeout)، درخواست به ایندکس SQLite FTS5 ارجاع داده میشود (fallback). این طراحی «ایمن در برابر خطا» (fail-safe) تضمین میکند که یک اختلال شبکه هرگز باعث خالی ماندن نوار جستجو نشود.
نگاشت چند-فیلدی (Multi-field mapping)
هر عنوان ویدئو به سه روش در OpenSearch ایندکس میشود:
- title.std – توسط یک تحلیلگر استاندارد (standard analyzer) با قابلیت ASCII folding پردازش میشود. این کار کاراکترهای دارای آکسان را نرمالسازی کرده و اکثر غلطهای تایپی در حروف لاتین را مدیریت میکند.
- title.cjk – توسط یک تحلیلگر CJK پردازش میشود که bigramها (توکنهای دو کاراکتری) ایجاد میکند. این کار قدرت تطبیق زیررشتهای را که FTS5 برای خطوط آسیایی فراهم میکند، حفظ میکند.
- title.keyword – بدون تغییر برای جستجوهای تطبیق دقیق (exact-match) و مرتبسازی ذخیره میشود.
فیلدهای مجزا اجازه میدهند تا پرسوجو بدون ترکیب استراتژیهای توکنسازی (tokenisation)، تحلیل مناسب را برای هر خط اعمال کند.
سطوح اولویتبندی (Boost tiers)
تیم به جای یک پرسوجوی یکپارچه و سنگین، یک پرسوجوی لایهبندی شده ساخت که نتایج را به طور خودکار رتبهبندی میکند:
- تطبیق عبارت دقیق در
title.keywordبالاترین میزان boost را دریافت میکند تا اطمینان حاصل شود که تطبیقهای کامل در صدر لیست قرار میگیرند. - تطبیق bigramهای CJK در
title.cjkمیزان boost متوسطی دریافت میکند تا کیفیت جستجوهای زبانهای آسیایی حفظ شود. - تطبیق فازی لاتین در
title.stdمیزان boost کمتری دریافت میکند تا نتایج با تحمل غلط تایپی ظاهر شوند، بدون اینکه نتایج دقیق را تحتالشعاع قرار دهند.
این رویکرد لایهبندی شده، تنظیم کردن (tuning) را ساده میکند: با تغییر یک مقدار boost، اهمیت نسبی کل یک دسته از تطبیقها تغییر میکند.
فازیسازی هوشمند (Smart fuzziness)
قابلیت فازیسازی (fuzziness) — که اجازه تعداد محدودی ویرایش کاراکتر را میدهد — فقط برای فیلد لاتین اعمال میشود. تیم قابلیت فازیسازی را برای title.cjk غیرفعال کرد، زیرا تغییر تنها یک کاراکتر در زبانهای CJK اغلب معنا را کاملاً تغییر میدهد. برای متن لاتین، پرسوجو از تنظیمات AUTO در OpenSearch استفاده میکند که فاصله ویرایش مجاز را بر اساس طول کلمه مقیاسبندی میکند و تعادلی بین تحمل خطا و مرتبط بودن نتایج ایجاد مینماید.
عملکرد و منطق جایگزینی (fallback)
روتین جستجو، فراخوانی OpenSearch را در یک بلوک try-catch قرار میدهد:
- اگر OpenSearch ظرف ۴۰۰ میلیثانیه پاسخ دهد، نتایج آن نمایش داده میشود.
- اگر فراخوانی با خطا مواجه شود یا از زمان تعیینشده (timeout) فراتر رود، سیستم بلافاصله پرسوجو را روی SQLite FTS5 مجدداً اجرا میکند.
این امر تضمین میکند که تأخیر شبکه یا قطعی سرویس هرگز تجربه کاربری را کاهش ندهد. تأخیر جستجو زیر ۲۰ میلیثانیه باقی ماند.
تأثیرات قابل اندازهگیری
- نرخ جستجوهای بدون نتیجه برای پرسوجوهای لاتین از ۱۱.۴٪ به ۲.۱٪ کاهش یافت.
- کیفیت جستجو برای پرسوجوهای CJK بدون تغییر باقی ماند که تأیید میکند تحلیلگر جدید CJK قدرت ایندکس اصلی FTS5 را حفظ کرده است.
- تأخیر سرتاسری (end-to-end) به راحتی زیر هدف ۲۰ میلیثانیه باقی ماند، به این معنی که لایه اضافه شده باعث کند شدن رابط کاربری (UI) نشد.
درسها و موازنهها (Lessons and trade-offs)
- جداسازی folding و fuzziness – قابلیت folding (نرمالسازی کاراکترها) و fuzziness (مدیریت غلطهای تایپی) مشکلات متفاوتی را حل میکنند. نگه داشتن آنها در فیلدهای مجزا از تداخلهای ناخواسته جلوگیری میکند.
- ایندکس جستجو را به عنوان منبع اصلی دادهها در نظر نگیرید – SQLite همچنان ذخیرهساز اصلی (canonical store) باقی میماند؛ OpenSearch یک نمای مشتقشده و قابل بازسازی است. این کار از انحراف ایندکس (index drift) جلوگیری کرده و بازیابی پس از خطاها را ساده میکند.
- سطوح اولویتبندی (Boost tiers) تنظیمات را ساده میکنند – گروهبندی تطبیقهای مرتبط تحت یک فاکتور boost واحد، تعداد پارامترهایی را که نیاز به تنظیم دارند کاهش میدهد.
آنچه در آینده باید زیر نظر داشت
این آزمایش ثابت میکند که یک لایه سبک OpenSearch میتواند بدون از دست دادن قابلیتهای اثباتشده CJK در SQLite FTS5، تحمل غلطهای تایپی را برای عناوین ویدئوهای چندزبانه به طرز چشمگیری بهبود بخشد. برای پلتفرمهایی که در آنها میزان مرتبط بودن نتایج جستجو مستقیماً بر زمان تماشا تأثیر میگذارد، این بهبود به یک موفقیت ملموس در تجربه کاربری تبدیل میشود.
