Autor Zpráva
Petr Ká
Profil
Ahoj,

řeším takový zajímavý problém, mám tabulku, kde jsou 3 sloupce s texty o cca 200 znacích (cca 12 000 000 řádků). Potřeboval bych vytáhnout třeba 100 nejčastěji vyskytovaných slov z textů v oněch 3 sloupcích (pro příklad text1, text2, text3) a aby toho nebylo málo, tak ještě s limitem minimálního počtu znaků (eliminace spojek, zkratek atd)...

Určitě bych věděl, jak to udělat pomocí PHP, případně pomocí druhé tabulky (INSERT IGNORE...), ale potřeboval bych to nějak aktualizovat (třeba co den), tak hledám způsob, zda by to šlo jednodušeji, na úrovni DB dotazem.

V nouzi bych si asi napsal proceduru, ale třeba to lze vyřešit jednoduše.

Jedná se o MySQL.
Kajman
Profil
Něco jako
SELECT text0,
       Sum(pocet) AS vyskytu
FROM   (SELECT text1    AS text0,
               Count(*) AS pocet
        FROM   tabulka
        WHERE  Length(text1) > 3
        GROUP  BY text1
        UNION ALL
        SELECT text2    AS text0,
               Count(*) AS pocet
        FROM   tabulka
        WHERE  Length(text2) > 3
        GROUP  BY text2
        UNION ALL
        SELECT text3    AS text0,
               Count(*) AS pocet
        FROM   tabulka
        WHERE  Length(text3) > 3
        GROUP  BY text3) t
GROUP  BY text0
ORDER  BY vyskytu DESC
LIMIT  100  
Petr Ká
Profil
Kajman:
Perfekt! Dá se říci, že je to přesně ono, nicméně, potřebuji, jak jsem psal, právě pro každé slovo ("explodnout" text na řádku podle mezery,čárky, tečky, otazníku, vykřičníku a podobně - nejlépe ještě podle LOWERCASE)

V praxi teda GROUPovat podle slov, ne podle celého textu na řádku.
Nevím, zda nechci moc a je to reálné, ale konkrétně na datech (sesbíraná při procházení českým internetem)

Reálně tedy dané SQL:
SELECT text0,
       Sum(pocet) AS vyskytu
FROM   (SELECT title AS text0,
               Count(*) AS pocet
        FROM   aa_spider
        WHERE  Length(title) > 3
        GROUP  BY title
        UNION ALL
        SELECT description AS text0,
               Count(*) AS pocet
        FROM   aa_spider
        WHERE  Length(description) > 3
        GROUP  BY description 
        UNION ALL
        SELECT keywords AS text0,
               Count(*) AS pocet
        FROM   aa_spider
        WHERE  Length(keywords ) > 3
        GROUP  BY keywords ) t
GROUP  BY text0
ORDER  BY vyskytu DESC
LIMIT  100

Vyhodí tento výsledek: http://screenshot.co/#!/b8fb916a72


DODATEK:
Abych lépe upřesnil, co mám na mysli, pokusím se to vyjádřit pomocí PHP kódu:

<?php 
$vety = $db->select('SELECT LOWER(CONCAT(title," ", description," ", keywords)) AS celek FROM `aa_spider`');
$slova = array();
foreach($vety as $veta){
    $veta["celek"] = str_replace(array(".",",","?","!")," ",$veta["celek"]);
    $casti = array_map("trim",explode(" ",trim($veta["celek"])));
    foreach ($casti as $cast){
        if (strlen($cast)<4) continue;
        if (!isset($slova[$cast])){
            $slova[$cast]=1;
        } else $slova[$cast]++;
    }
}
arsort($slova);
$limit = 100;
$pozice = 0;
foreach ($slova as $slovo=>$pocet){
    $pozice++;
    echo "#".$pozice." - ".$slovo." (".$pocet."x)<br >";
    if ($pozice>=$limit) break;
}
?>

A to mi vrátí požadovyný výsledek:

#1 - nejprodávanější (88055x)
#2 - ubytování (73356x)
#3 - doména (57344x)
#4 - zdarma (53543x)
#5 - tato (51278x)
#6 - amber (50739x)
#7 - nebyla (50729x)
#8 - nalezena (50701x)
#9 - node (50688x)
#10 - každý (45603x)
#11 - sekce (44326x)
#12 - řady (44252x)
#13 - pořiďte (44139x)
#14 - kousek (44104x)
#15 - detaily (44027x)
#16 - pyšní (43985x)
#17 - funkčností (43982x)
#18 - kousků (43978x)
#19 - vychytanými (43972x)
#20 - několikero (43966x)
#21 - obchod (39095x)
#22 - praha (38025x)
#23 - prodej (37943x)
#24 - výprodej (35755x)
#25 - eshop (35677x)
#26 - nejlevnější (31972x)
#27 - recenze (31467x)
#28 - kvality (27848x)
#29 - stránky (27530x)
#30 - záruka (27386x)
#31 - zboží (27222x)
#32 - ověřený (26354x)
#33 - hotel (25432x)
#34 - online (25185x)
#35 - dámské (23872x)
#36 - srovnání (22101x)
#37 - rezervace (21752x)
#38 - levné (21630x)
#39 - rock (20939x)
#40 - ceny (20914x)
#41 - restaurace (19811x)
#42 - brno (18790x)
#43 - úvod (17970x)
#44 - slevy (17937x)
#45 - zeď (17889x)
#46 - penzion (17139x)
#47 - servis (16912x)
#48 - práce (16777x)
#49 - blog (16343x)
#50 - nejlepší (16043x)
.
.
.
.
.
.
Kajman
Profil
Tak v takovém případě použijte to php.
Petr Ká
Profil
Kajman:
Myslel jsem si to, ze to tak bude, MySQL iterace nezvládá. Děkuji

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: