איך הוספתי חיפוש עמיד לטעויות כתיב עם OpenSearch ו-CJK

שאילתות ללא תוצאות הרסו לנו את זמן הצפייה.

במשך שנה, TopVideoHub השתמש ב-SQLite FTS5 לצורך חיפוש. זה עבד עבור התאמות מדויקות, אך נכשל כאשר משתמשים ביצעו טעויות כתיב.

אנשים חיפשו "demon slyer" במקום "demon slayer". הם הוסיפו רווחים מיותרים בכותרות ביפנית או בקוריאנית. מכיוון ש-FTS5 מתאים טוקנים (tokens) מדויקים, טעות כתיב אחת גרמה לאפס תוצאות. המשתמשים לא חיפשו שוב; הם פשוט עזבו.

העברתי את חיפוש הכותרות שלנו ל-OpenSearch. הנה איך פתרתי את זה עבור קהל רב-לשוני.

הבעיה עם fuzziness סטנדרטי

רוב המדריכים יגידו לכם להשתמש ב-"fuzziness" כדי לתקן טעויות כתיב. זה עובד עבור אנגלית, אך זה נכשל בטקסט בסינית, יפנית וקוריאנית (CJK).

  • edit distance אינו מתאים ל-CJK. טעות כתיב ב-CJK פירושה לעיתים קרובות שימוש בתו (character) שגוי לחלוטין.
  • fuzziness סטנדרטי יוצר "זבל סמנטי". הוא עלול להתאים בין "fire" ל-"water" כי הם במרחק עריכה אחד זה מזה.
  • tokenization היא משימה קשה. שפות CJK אינן משתמשות ברווחים בין מילים.

הפתרון: גישת רב-שדות (Multi-Field Approach)

הפסקתי להתייחס לכל הטקסט באותו אופן. יצרתי שדה כותרת לוגי אחד המאנדקס בשלוש דרכים שונות:

  • לטינית ורומאג'י (Romaji): השתמשתי ב-tokenization סטנדרטי עם fuzziness מופעל. הגדרתי prefix length של 1. זה מבטיח ש-"demon" יתאים ל-"demn", אך "lemon" לא יתאים ל-"demon".
  • טקסט CJK: השתמשתי ב-CJK bigram analyzer וב-ICU normalizer. כיביתי את ה-fuzziness. במקום זאת, השתמשתי ב-minimum match threshold של 70%.
  • Autocomplete: השתמשתי בשדה edge-ngram כדי להפעיל תוצאות מסוג search-as-you-type.

ארכיטקטורה ובטיחות נתונים

שמרתי על SQLite כ-single source of truth. OpenSearch משמש כאינדקס מהיר שניתן לבנייה מחדש.

  • אני משתמש ב-PHP כדי לדחוף עדכונים ל-OpenSearch ב-bulk batches.
  • אני לעולם לא מריץ indexing במהלך בקשת משתמש.
  • אני מריץ סקריפט Python כדי לבדוק "סטייה" (drift). זה מבטיח שספירת הנתונים ב-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