Wie ich eine tippfehler-tolerante Suche mit OpenSearch und CJK implementiert habe

Suchanfragen ohne Ergebnisse haben unsere Watchtime ruiniert.

Ein Jahr lang nutzte TopVideoHub SQLite FTS5 für die Suche. Bei exakten Treffern funktionierte es. Bei Tippfehlern versagte es jedoch.

Nutzer suchten nach „demon slyer“ statt „demon slayer“. Sie fügten versehentliche Leerzeichen in japanischen oder koreanischen Titeln ein. Da FTS5 exakte Token abgleicht, bedeutete ein einziger Tippfehler null Ergebnisse. Die Nutzer versuchten es nicht noch einmal. Sie gingen einfach.

Ich habe unsere Titelsuche auf OpenSearch umgestellt. Hier ist, wie ich das Problem für ein mehrsprachiges Publikum gelöst habe.

Das Problem mit Standard-Fuzziness

Die meisten Tutorials raten dazu, „Fuzziness“ zu verwenden, um Tippfehler zu beheben. Das funktioniert für Englisch, scheitert aber bei chinesischen, japanischen und koreanischen (CJK) Texten.

  • Die Edit-Distanz ist für CJK ungeeignet. Ein Tippfehler in CJK bedeutet oft, dass ein völlig falsches Schriftzeichen verwendet wird.
  • Standard-Fuzziness erzeugt semantischen Müll. Sie könnte „fire“ mit „water“ abgleichen, nur weil sie nur eine Änderung voneinander entfernt sind.
  • Die Tokenisierung ist schwierig. CJK-Sprachen verwenden keine Leerzeichen zwischen Wörtern.

Die Lösung: Ein Multi-Field-Ansatz

Ich habe aufgehört, alle Texte gleich zu behandeln. Ich habe ein logisches Titelfeld erstellt, das auf drei verschiedene Arten indiziert wird:

  • Lateinisch und Romaji: Ich habe die Standard-Tokenisierung mit aktiviertem Fuzziness verwendet. Ich habe eine Prefix-Länge von 1 festgelegt. Dies stellt sicher, dass „demon“ mit „demn“ übereinstimmt, „lemon“ aber nicht mit „demon“.
  • CJK-Text: Ich habe einen CJK-Bigram-Analyzer und einen ICU-Normalizer verwendet. Ich habe Fuzziness AUSgeschaltet. Stattdessen habe ich eine Mindestübereinstimmungsschwelle (minimum match threshold) von 70 % verwendet.
  • Autocomplete: Ich habe ein Edge-Ngram-Feld verwendet, um „Search-as-you-type“-Ergebnisse zu ermöglichen.

Architektur und Datensicherheit

Ich habe SQLite als „Single Source of Truth“ beibehalten. OpenSearch fungiert als schneller, jederzeit neu aufbaubarer Index.

  • Ich verwende PHP, um Updates in Bulk-Batches an OpenSearch zu senden.
  • Ich führe die Indizierung niemals während einer Benutzeranfrage aus.
  • Ich lasse ein Python-Skript laufen, um nach „Drift“ zu suchen. Dies stellt sicher, dass die Anzahl in OpenSearch mit der Anzahl in SQLite übereinstimmt.

Die Ergebnisse

Die Änderung war gewaltig:

  • Suchanfragen ohne Ergebnisse sanken von 14 % auf unter 3 %.
  • Die Suchsitzungen wurden länger, da die Nutzer sofort fanden, was sie suchten.
  • Die Latenz bleibt mit etwa 40 ms niedrig.

Wenn Sie ein mehrsprachiges Publikum bedienen, denken Sie daran: Tippfehler-Toleranz und CJK-Matching sind zwei verschiedene Probleme. Sie benötigen zwei verschiedene Lösungen.

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