میں نے OpenSearch اور CJK کے ساتھ ٹائپو-ٹولرنٹ سرچ کیسے شامل کیا

زیرو-ریزولٹ (صفر نتائج والی) کوئریز ہمارے واچ ٹائم کو تباہ کر رہی تھیں۔

ایک سال تک، TopVideoHub سرچ کے لیے SQLite FTS5 استعمال کرتا رہا۔ یہ درست میچز کے لیے تو ٹھیک کام کرتا تھا، لیکن جب صارفین ٹائپو (لکھنے میں غلطی) کرتے تو یہ ناکام ہو جاتا تھا۔

لوگ "demon slayer" کے بجائے "demon slyer" تلاش کرتے تھے۔ وہ جاپانی یا کوریائی عنوانات میں غیر ضروری سپیس (space) ڈال دیتے تھے۔ چونکہ FTS5 صرف درست ٹوکنز (tokens) کو میچ کرتا ہے، اس لیے ایک چھوٹی سی غلطی کا مطلب صفر نتائج ہوتا تھا۔ صارفین دوبارہ تلاش نہیں کرتے تھے، بلکہ وہ بس ایپ چھوڑ کر چلے جاتے۔

میں نے اپنے ٹائٹل سرچ کو OpenSearch پر منتقل کر دیا۔ یہاں بتایا گیا ہے کہ میں نے کثیر لسانی (multilingual) سامعین کے لیے اس مسئلے کو کیسے حل کیا۔

اسٹینڈرڈ فزی نیس (Standard Fuzziness) کے ساتھ مسئلہ

زیادہ تر ٹیوٹوریلز ٹائپو ٹھیک کرنے کے لیے "fuzziness" استعمال کرنے کا مشورہ دیتے ہیں۔ یہ انگریزی کے لیے تو کام کرتا ہے، لیکن چینی، جاپانی اور کوریائی (CJK) متن کے لیے ناکام رہتا ہے۔

  • ایڈٹ ڈسٹنس (Edit distance) CJK کے لیے نقصان دہ ہے۔ CJK میں ٹائپو کا مطلب اکثر مکمل طور پر غلط حرف کا استعمال ہوتا ہے۔
  • اسٹینڈرڈ فزی نیس سے مفہومی کچرا (semantic garbage) پیدا ہوتا ہے۔ یہ "fire" کو "water" کے ساتھ میچ کر سکتا ہے کیونکہ ان کے درمیان صرف ایک ایڈٹ کا فرق ہے۔
  • ٹوکنائزیشن (Tokenization) مشکل ہے۔ CJK زبانوں میں الفاظ کے درمیان سپیس استعمال نہیں ہوتی۔

حل: ایک ملٹی فیلڈ اپروچ (Multi-Field Approach)

میں نے تمام متن کے ساتھ ایک جیسا سلوک کرنا بند کر دیا۔ میں نے ایک لاجیکل ٹائٹل فیلڈ بنائی جو تین مختلف طریقوں سے انڈیکس کرتی ہے:

  • Latin and Romaji: میں نے فزی نیس (fuzziness) کے ساتھ اسٹینڈرڈ ٹوکنائزیشن استعمال کی۔ میں نے پری فکس لینتھ (prefix length) 1 سیٹ کی۔ اس سے یہ یقینی بنتا ہے کہ "demon" کا میچ "demn" سے ہو جائے لیکن "lemon" کا میچ "demon" سے نہ ہو۔
  • CJK Text: میں نے CJK bigram analyzer اور ICU normalizer استعمال کیا۔ میں نے فزی نیس کو OFF کر دیا۔ اس کے بجائے، میں نے 70% کی کم از کم میچ تھریش ہولڈ (minimum match threshold) استعمال کی۔
  • Autocomplete: میں نے سرچ-ایز-یو-ٹائپ (search-as-you-type) نتائج کے لیے ایک edge-ngram فیلڈ استعمال کی۔

آرکیٹیکچر اور ڈیٹا کی حفاظت

میں نے SQLite کو واحد مستند ذریعہ (single source of truth) کے طور پر برقرار رکھا۔ OpenSearch ایک تیز رفتار اور دوبارہ تعمیر ہونے والے انڈیکس کے طور پر کام کرتا ہے۔

  • میں OpenSearch میں بلک بیچز (bulk batches) میں اپ ڈیٹس بھیجنے کے لیے PHP استعمال کرتا ہوں۔
  • میں صارف کی درخواست (user request) کے دوران انڈیکسنگ کبھی نہیں چلاتا۔
  • میں "ڈرفٹ" (drift) چیک کرنے کے لیے ایک Python اسکرپٹ چلاتا ہوں۔ یہ یقینی بناتا ہے کہ OpenSearch کا کاؤنٹ SQLite کے کاؤنٹ سے مطابقت رکھتا ہو۔

نتائج

تبدیلی بہت بڑی تھی:

  • زیرو-ریزولٹ کوئریز 14% سے کم ہو کر 3% سے بھی نیچے آ گئیں۔
  • سرچ سیشنز طویل ہو گئے کیونکہ صارفین کو جو چاہیے تھا وہ فوراً مل گیا۔
  • لیٹنسی (Latency) تقریباً 40ms پر کم رہی۔

اگر آپ کثیر لسانی سامعین کو سروس فراہم کرتے ہیں، تو یاد رکھیں: ٹائپو ٹولرنس اور CJK میچنگ دو الگ الگ مسائل ہیں۔ آپ کو دو الگ الگ حل درکار ہوں گے۔

ماخذ: https://dev.to/ahmet_gedik778845/how-i-added-typo-tolerant-video-title-search-with-opensearch-and-cjk-3e5d