Wyszukiwanie frazy w ciągu znaków

0

Mamy dwa ciągi znaków.

Dłuższy np. "Piszę w sprawie Jan Kowalski" i listę możliwych użytkowników.

Chciałbym określić o jakiej osobie mowa jest w zdaniu, oczywiście najłatwiejsza opcja to sprawdzenie czy występuje w ciągu znaków imię i nazwisko oraz ewentualnie odwrotność. Ok, to mamy z z głowy, ale algorytm musi być bardziej zaawansowany i wykryć odmiany np. Jana Kowalskiego, Janka Kowalski itp. Nie zależy mi na 100% rozpoznaniu, wystarczy mi najbardziej zbliżony. Ktoś się kiedyś zmierzył?

Póki co mam 3 prototypy.

  1. Full index.
select id, title, score from (SELECT id, title, MATCH (`title`) AGAINST('(Paweł* Żyra*) ("Paweł Żyra")'  IN BOOLEAN MODE) as score FROM titles) t where `id` = 3 group by `score` having `score` > 0 order by `score` desc limit 1

To najbardziej udane rozwiązanie, radzi sobie dość dobrze ale jest taki moment że po prostu się zacina i score wskakuje na zero np. przy frazie "Pawła Żyry" (ale radzi sobie jeszcze z np. "za Pawla Zyra"). Dużymm minusem jest optymalność, jak widać to wykonuje tyle zapytań ile mamy do przeszukania tytułów i nazwisk ponieważ nie da się wyszukiwać po wielu frazach.

  1. Similar text

Czasem daje super wyniki, czasem beznadziejne. Z pewnością było by to dobre gdybym miał pewność że w title jest tylko imię i nazwisko.

  1. levenshtein

Podobnie jak wyżej.

2 i 3 są znacznie szybsze i dają łatwiejszą manipulacje (np. mogę bez problemu wyciąć pl znaki i je ignorować, w mysql tego w locie nie potrafię zrobić albo byłoby to skomplikowane).

0

a po prostu

SELECT * FROM costam WHERE title LIKE '%Jan%' AND WHERE title LIKE '%Kowalski%'

Cały problem, że polegniesz jeśli dane imie/nazwisko przy odmianie zmienia też coś w zasadniczym członie no i zawsze znajdą się false-posiivy

0

Zwykły LIKE to poziom niżej niż rozwiązanie nr 1. Polegnie już na każdym damskim imieniu np. Karolina / Karolinę.

0

Myślę, że nie da się zrobić tego idealnie. Imiona i nazwiska mogą mieć różne sposoby odmiany, więc nie da się stworzyć wzorca. Chyba musiałbyś spróbować stworzyć jakiś słownik odmian. Jeden dla imion i jeden dla nazwisk. I potem to porównywać.

Ewentualnie, zamiast budować rozbudowany słownik z wszystkimi odmianami, to zamiast odmian można spróbować się ograniczyć do części wspólnych:

  • dla Paweł będziesz miał np.: "Paweł", "Pawel", "Pawł" i "Pawl". Wtedy nie trzeba dodawać odmian w stylu: Pawła, Pawłowi, Pawłom, itp.
  • dla Żyra będzie np. coś w stylu "Żyr"

Levenshteina (najbliższy odpowiednik w MySQL to chyba SOUNDEX) bym odrzucił - tak jak pisałeś, mogą wyjść czasem dziwne wyniki.

0

Ze słownikami nie ma szans, nie chce takiego sztywnego rozwiązania poza tym co z nazwiskami?
SOUNDEX działa chyba tylko dobrze ale języka angielskiego więc odpada.

Generalnie poradziłem sobie z tematem, napisałem własny algorytm w oparciu o similar_text badający pary, zamiast całego tekstu + kilka innych czynników mniej istotnych, ale też wpływających na "score".

0

Po co takie rozwiązanie ?

1 użytkowników online, w tym zalogowanych: 0, gości: 1