Jednoduché vyhledávání v MySQL, MariaDB a PostgreSQL

petersveter

Chcel by som implementovat full text vyhladavanie pre beznu db(maria). Nechcem ziadnu externu zavyslost ako sphinx, elastic, solr...

V principe by sa text tokenizoval a vlozil do db ako tri stlpce: slovo, id obsahu, pocet vysktov v obsahu. Tokenizacia znamena ze text sa rozdeli na slova, s min/max dlzkou, transliteruje sa, minimalizuje sa pismo a tak sa potom identifikuje. Cize slovo "Přeshraniční" by bolo tokenizovane ako "preshranicni".

Vyhladavanie sa potom taktiez tokenizuje a vysledky sa zoradia podla poctu vyskytov slova v obsahu.

Skratka take zakladne vyhladavanie ktore postaci pre 90% pripadov.

Moja otazka je, ako by sa dalo pristupit k preklepom? Inak povedane, ako by sa dalo vyhladavat podla podobnosti slova? Cize ak niekto hlada "přehsraniční" namiesto "přeshraniční" tak mu to najde spravny vysledok. Je tu len jedno prehodniee slov no dost vyznamne, na rozdiel od napriklad "přeshraniční" vs "řeshraniční".

Treba nejak sledovat ktore slova/vysledky sa paruju s akymi frazami alebo pouzit nejaky pattern matching?

Neviem ci sa tento koncept vola fuzzy search alebo proximity search...ale teda ci je to aj mozne nejak jednoducho implementovat v beznej db?
« Poslední změna: 09. 02. 2024, 12:38:23 od Petr Krčmář »


Re:Jednoduche full text vyhladavanie v MySql/MariaDb/Postgre
« Odpověď #1 kdy: 09. 02. 2024, 12:36:01 »
pokud ti stačí tokenizace po slovech, udělej si velkou faktovou tabulku s klasickým indexem a referencí na původní dokument. Máš vyhráno, teda nemáš.

Překlepy se dají s jistou mírou úspěšnosti řešit přes levenshteina, ten se dá dobře implementovat přes udf v mysql. V počátcích jsme překlepy aliasovali ručně, koukali jsme na vstupy s málo výsledky a přiřazovali k tomu alias, za pár měsíců se vybudovala slušná a relevantní databáze. To bylo před 20 lety.

Dnes obstojně fulltext umí postgresql (přes tsvector), má lemnizaci, tokenizaci po slabikách, fuzzy.

Proč se tak bráníte externí závislosti, projekty typu https://github.com/meilisearch/meilisearch vám usnadní velice práci a jedná se o jednu službu v jedné binárce se stabilním api. Nebo třeba https://github.com/typesense/typesense či https://github.com/zincsearch/zincsearch a sposty dalších.

petersveter

Re:Jednoduche full text vyhladavanie v MySql/MariaDb/Postgre
« Odpověď #2 kdy: 09. 02. 2024, 13:22:27 »
Proč se tak bráníte externí závislosti

Znamena to dalsi server a aplikaciu na spravu logiky a td. Do buducna urcite ale aktualne nie.

Re:Jednoduché vyhledávání v MySQL, MariaDB a PostgreSQL
« Odpověď #3 kdy: 09. 02. 2024, 14:26:21 »
copak to nemůžeš běžet na stejné serveru jako mysql? Logiku stejně musíš nějak spravovat, data tam nalívat, filtrovat, mazat stará. Obecně platí, že fulltext databáze neobsahuje master data (tj. originály máš jinde).

Naopak trvání na mysql, která má podporu dost slabou a při velké množství textů se rychle zahltí (chybí jí nějaké optimalizace pro vectory a sparse indexy) může prodražit vývoj, ladění i provoz.

Jak to přibližně udělat v mysql jsem ti napsal, moc víc toho tam vymyslet nelze.

Re:Jednoduché vyhledávání v MySQL, MariaDB a PostgreSQL
« Odpověď #4 kdy: 09. 02. 2024, 14:34:42 »
Postgres umí řadit na základě podobnosti:

postgres=> select * from obce order by nazev <-> 'Skaice' limit 5;
┌──────┬──────────┬──────────┬────────────┬───────────┬──────────┬─────────┐
│  id  │ okres_id │  nazev   │ pocet_muzu │ pocet_zen │ vek_muzu │ vek_zen │
╞══════╪══════════╪══════════╪════════════╪═══════════╪══════════╪═════════╡
│ 3049 │ CZ0521   │ Skalice  │        288 │       281 │     38.3 │    41.5 │
│ 5203 │ CZ0647   │ Skalice  │        247 │       318 │     39.1 │    46.6 │
│ 1735 │ CZ0317   │ Skalice  │        230 │       241 │     41.6 │    42.7 │
│ 5705 │ CZ0721   │ Skaštice │        198 │       186 │     37.8 │    39.5 │
│ 2253 │ CZ0327   │ Skapce   │         54 │        53 │     37.1 │    40.2 │
└──────┴──────────┴──────────┴────────────┴───────────┴──────────┴─────────┘
(5 řádek)

postgres=> select * from obce order by nazev <-> 'Skalic' limit 5;
┌──────┬──────────┬──────────┬────────────┬───────────┬──────────┬─────────┐
│  id  │ okres_id │  nazev   │ pocet_muzu │ pocet_zen │ vek_muzu │ vek_zen │
╞══════╪══════════╪══════════╪════════════╪═══════════╪══════════╪═════════╡
│ 3049 │ CZ0521   │ Skalice  │        288 │       281 │     38.3 │    41.5 │
│ 1735 │ CZ0317   │ Skalice  │        230 │       241 │     41.6 │    42.7 │
│ 5203 │ CZ0647   │ Skalice  │        247 │       318 │     39.1 │    46.6 │
│ 4826 │ CZ0643   │ Skalička │         53 │        49 │     34.6 │    39.9 │
│ 5543 │ CZ0714   │ Skalička │        235 │       313 │     38.3 │    38.7 │
└──────┴──────────┴──────────┴────────────┴───────────┴──────────┴─────────┘
(5 řádek)



petersveter

Re:Jednoduché vyhledávání v MySQL, MariaDB a PostgreSQL
« Odpověď #5 kdy: 09. 02. 2024, 15:33:09 »
Postgres umí řadit na základě podobnosti:

Viem ze bezne db maju nativnu podporu pre mnoho veci ohladom vyhladavania dnes, skor mi islo o vlastnu implementaciu(nech sa naucim nieco nove).

Re:Jednoduché vyhledávání v MySQL, MariaDB a PostgreSQL
« Odpověď #6 kdy: 09. 02. 2024, 15:38:17 »
v tom případě asi nehledej řešení na fóru, ale podívej se do zdrojáků existujících řešení a na použité algoritmy.