Zespół deweloperski połączył OpenSearch z SQLite FTS5 i zredukował liczbę wyszukiwań wideo bez wyników z 11,4% do 2,1%, zachowując przy tym opóźnienie poniżej 20 ms. Teraz użytkownicy wpisujący „blackpink jenny solo stag” widzą poprawne „BLACKPINK Jennie SOLO stage” zamiast pustej listy.

Dlaczego wprowadzono tę zmianę

Logi wyszukiwania z platformy hostingowej wideo wykazały powtarzający się problem: pojedyncza literówka w tytule zapisanym alfabetem łacińskim mogła wyeliminować wszystkie dopasowania. Rozszerzenie SQLite FTS5, cenione za zdolność do dopasowywania podciągów w tekstach chińskich, japońskich i koreańskich (CJK), nie obsługuje dopasowania rozmytego (fuzzy matching). Jeden błędnie napisany znak w nazwisku lub tytule piosenki całkowicie przerywa zapytanie.

Istniejący potok przetwarzania traktował SQLite jako jedyny indeks. Dobrze radził sobie z zapytaniami CJK, ale nie oferował żadnego zabezpieczenia przed literówkami w alfabecie łacińskim. Zespół poszukiwał zatem uzupełniającego silnika wyszukiwania, który zapewniłby odporność na literówki bez rezygnacji ze sprawdzonej warstwy FTS5.

Jak dodano OpenSearch

OpenSearch działa jako usługa wyszukiwania pierwszej linii, podczas gdy SQLite pozostaje źródłem prawdy (source of truth). Oba systemy działają równolegle: OpenSearch najpierw odbiera zapytanie użytkownika i jeśli odpowie wystarczająco szybko, jego wyniki są wyświetlane. Jeśli OpenSearch przekroczy limit czasu lub wystąpi błąd, zapytanie przełącza się na indeks SQLite FTS5. Taka konstrukcja typu „fail-safe” gwarantuje, że chwilowe problemy z siecią nigdy nie pozostawią paska wyszukiwania pustego.

Mapowanie wielu pól

Każdy tytuł wideo jest indeksowany w OpenSearch na trzy sposoby:

  • title.std – przetwarzany przez standardowy analizator z ASCII foldingiem. Normalizuje on znaki diakrytyczne i obsługuje większość literówek w alfabecie łacińskim.
  • title.cjk – przetwarzany przez analizator CJK, który tworzy bigramy (dwuznakowe tokeny). Pozwala to zachować siłę dopasowywania podciągów, którą FTS5 zapewnia dla pism azjatyckich.
  • title.keyword – przechowywany bez zmian do wyszukiwania dokładnych dopasowań i sortowania.

Oddzielne pola pozwalają na zastosowanie odpowiedniej analizy do każdego rodzaju pisma bez mieszania strategii tokenizacji.

Warstwy boostu

Zamiast pojedynczego, monolitycznego zapytania, zespół zbudował zapytanie warstwowe, które automatycznie ranguje wyniki:

  1. Dokładne dopasowania fraz w title.keyword otrzymują najwyższy boost, co zapewnia, że idealne dopasowania dominują na liście.
  2. Dopasowania bigramów CJK w title.cjk otrzymują średni boost, co zachowuje jakość wyszukiwania w językach azjatyckich.
  3. Rozmyte dopasowania łacińskie w title.std otrzymują niższy boost, co pozwala na wyświetlanie wyników odpornych na literówki bez przyćmiewania dokładnych trafień.

Podejście warstwowe sprawia, że strojenie jest proste: zmiana jednej wartości boostu zmienia relatywne znaczenie całej klasy dopasowań.

Inteligentne dopasowanie rozmyte (smart fuzziness)

Fuzziness — pozwalające na ograniczoną liczbę edycji znaków — dotyczy tylko pola łacińskiego. Zespół wyłączył fuzziness dla title.cjk, ponieważ zmiana pojedynczego znaku w CJK często całkowicie zmienia znaczenie słowa. Dla tekstu łacińskiego zapytanie wykorzystuje ustawienie fuzziness AUTO w OpenSearch, które skaluje dopuszczalną odległość edycji w zależności od długości słowa, zachowując równowagę między tolerancją a trafnością.

Wydajność i logika fallbacku

Rutyna wyszukiwania opakowuje wywołanie OpenSearch w blok try-catch:

  • Jeśli OpenSearch odpowie w ciągu 400 ms, jego wyniki są wyświetlane.
  • Jeśli wywołanie rzuci wyjątek lub przekroczy limit czasu, system natychmiast ponownie wykonuje zapytanie w SQLite FTS5.

Zapewnia to, że opóźnienia sieciowe lub awarie usług nigdy nie pogorszą doświadczenia użytkownika. Opóźnienie wyszukiwania pozostało poniżej 20 ms.

Mierzalny wpływ

  • Wskaźnik wyszukiwań bez wyników dla zapytań w alfabecie łacińskim spadł z 11,4% do 2,1%.
  • Jakość wyszukiwania dla zapytań CJK pozostała bez zmian, co potwierdza, że nowy analizator CJK zachował zalety oryginalnego indeksu FTS5.
  • Opóźnienie end-to-end utrzymało się komfortowo poniżej celu 20 ms, co oznacza, że dodana warstwa nie spowolniła interfejsu użytkownika.

Lekcje i kompromisy

  • Rozdzielenie folding i fuzziness – Folding (normalizacja znaków) i fuzziness (obsługa literówek) rozwiązują różne problemy. Przechowywanie ich na osobnych polach zapobiega niezamierzonym interakcjom.
  • Nie traktuj indeksu wyszukiwania jako źródła prawdy – SQLite pozostaje kanonicznym magazynem danych; OpenSearch jest pochodnym, odświeżalnym widokiem. Zapobiega to dryftowi indeksu i upraszcza odzyskiwanie danych po awariach.
  • Warstwy boostu upraszczają strojenie – Grupowanie powiązanych dopasowań pod jednym czynnikiem boostu zmniejsza liczbę parametrów wymagających regulacji.

Co dalej

Eksperyment dowodzi, że niewielka warstwa OpenSearch może drastycznie poprawić odporność na literówki w wielojęzycznych tytułach wideo, nie rezygnując przy tym ze sprawdzonych możliwości CJK modułu SQLite FTS5. Dla platform, na których trafność wyszukiwania bezpośrednio wpływa na czas oglądania, ta poprawa przekłada się na wymierną korzyść w obszarze doświadczenia użytkownika.