Kodulehed
Valitud koduleht: [368] - Andmebaasid I (IDU0220) (kevad 2018)
pinned Kiirvalik
Üldist
Materjalid
Vaated materjalidele
Tudeng
Abi
Mitmesugust
HELPDESK - teemad:

                         
Erki Eessaar:
Kuidas Mauruse otsing täpsemalt töötab? Millist tuge pakkus selle realiseerimiseks andmebaasisüsteem, mida Maurus kasutab?
Vastus: Mauruse kasutajad soovivad sageli, et seal oleks otsingu funktsionaalsus. Lisasin Maurusesse selle funktsionaalsuse. Otsing on võimalik kodulehe piires. Leiate võimaluse seda teha iga aine kodulehelt alajaotusest Üldist=>Otsing. Otsing toimub üle materjalide metaandmete, teadete, helpdeski küsimuste/vastuste ning viidete. Otsingu tulemused on ühel lehel nende kategooriate kaupa grupeerituna. Materjale, teateid ja helpdeski küsimusi/vastuseid on otsingu tulemuses igaühte kuni 10. Viiteid on tulemuses kuni 20. Materjalide puhul ei toimu otsing mitte failide sisu, vaid materjale kirjeldavate andmete (metaandmete) põhjal.

Kuna Maurus kasutab PostgreSQL andmebaasisüsteemi, siis tegi PostgreSQLi pakutav täisteksti otsingu funktsionaalsus selle funktsionaalsuse realiseerimise lihtsamaks.

Järgnevalt esitan koodinäite.

Näiteks oletame, et tahan lisada teadete otsimise võimaluse ning et andmebaasis on tabel Avalik_teade, üle mille veergude pealkiri ja sisu peaks otsing toimuma.

Avalik_teade(avalik_teade_id, pealkiri, sisu)
Primaarvõti(avalik_teade_id)

Lisan tabelisse veeru tsv, mis hakkab iga teate korral sisaldama spetsiaalset pealkirja ning sisu kokkuvõtet ja on ühtlasi aluseks nende alusel otsingute tegemisele. See veerg on tüüpi tsvector. See on spetsiifiline PostgreSQLi andmetüüp.

ALTER TABLE Avalik_teade ADD COLUMN tsv tsvector;

Loon tabeliga seotud trigeri, mis andmete tabelisse lisamisel või muutmisel värskendab veergudes pealkiri ja sisu olevate andmete põhjal veerus tsv olevaid andmeid. Kahjuks ei toeta kasutatav PostgreSQL versioon võimalust määrata, et triger peaks käivituma ainult siis, kui andmeid muudetakse (UPDATE) mingis kindlas veerus. Kahjuks ei ole täistektiotsingutel eesti keele tuge, tänu millele oskaks andmebaasisüsteem otsingu tegemisel arvestada keele eripäradega. Seega kasutan inglise keele (pg_catalog.english) reegleid.

CREATE TRIGGER teade_tsv_iu BEFORE INSERT OR UPDATE
ON Avalik_teade FOR EACH ROW EXECUTE PROCEDURE
tsvector_update_trigger(tsv, 'pg_catalog.english', pealkiri, sisu);

Teen andmemuudatuse, mis tänu eelnevale trigerile tingib andmete lisamise veergu tsv.

UPDATE Avalik_teade SET pealkiri=pealkiri;

Veerus tsv on nüüd andmed nagu: 26,231,261 'segamini':253 'sell':24 'sellel':100 'sellest':91 'sellis':132 '

Loon veerule tsv otsingu kiirendamiseks indeksi.

CREATE INDEX teade_tsv_idx ON Teade USING gin(tsv);

Muudan veeru tsv kohustuslikuks.

ALTER TABLE Teade ALTER COLUMN tsv SET NOT NULL;

Järgnev päring leiab tabelist Avalik_teade sellised teated, mis sisaldavad sõna "SQL". Päring väljastab teate identifikaatori, pealkirja, sisu ning pealkirja ja sisu põhjal moodustatud kokkuvõtte, kus on otsisõna esile tõstetud. Päringu tulemus on sorteeritud tulemuse relevantsuse hinnangu alusel kahanevalt.. Päringu tulemuses on maksimaalselt 10 rida..

coalesce funktsioon tagastab vasakult lugedes esimese argumendi, mis ei ole NULL. coalesce(pealkiri,'') avaldis tähendab, et kui pealkiri on olemas (pole NULL) tagastab funktsioon pealkirja, vastasel juhul teiseks argumendiks oleva tühja stringi. Tühi string ja NULL on kaks ise asja - tühi string on väärtus, kuid NULL on marker, mis tähistab väärtuse puudumist. coalesce läheb vaja, sest PostgreSQLi stringide ühendamise (konkatenatsiooni) operaator käitub juhul kui üks argument on NULL järgnevalt: 'tekst' || NULL => NULL. Juhuks kui teates pealkiri või sisu puudub tuleb enne nende ühendamist kontrollida kas üks nendest on NULL ja vajadusel asendada see tühja stringiga: 'tekst' || '' => ''tekst'

SELECT avalik_teade_id, pealkiri, sisu, ts_headline(coalesce(pealkiri,'') || ' ' || coalesce(sisu,''), q) AS fragment
FROM (SELECT avalik_teade_id, pealkiri, sisu, q, ts_rank_cd(tsv,q) AS rank
FROM Avalik_teade, to_tsquery('SQL') AS q
WHERE tsv @@ q

ORDER BY rank DESC
LIMIT 10) AS foo;

Kommentaarid

Sellele küsimusele/vastusele pole kommentaare



1.Erki Eessaar:
2.Erki Eessaar:
3.Erki Eessaar:
4.Erki Eessaar:
5.Erki Eessaar:
6.Erki Eessaar:
7.Erki Eessaar:
8.Anonüümne:
9.Erki Eessaar:
10.Erki Eessaar:
11.Erki Eessaar:
12.Erki Eessaar:
13.Erki Eessaar:
14.Erki Eessaar:
15.Anonüümne:
16.Erki Eessaar:
17.Erki Eessaar:
18.Erki Eessaar:
19.Erki Eessaar:
20.Erki Eessaar:
21.Anonüümne:
22.Erki Eessaar:
23.Erki Eessaar: