MongoDB - Text Search (Tekst pretraga)

MongoDB kao jedna od vodećih NoSQL baza, dobro je poznata po dobrim performansama, fleksibilnim šemama, skalabilnosti i sjajnim mogućnostima indeksiranja (koje je objašnjeno pre). Glavni "krivac" za dobre performanse MongoDB jesu indeksi, koji omogućavaju efikasno izvršavanje upita izbegavajući prelazak svih kolekcija već samo onih dokumenata koji ispunjavaju određene uslove.

Još od verzije 2.4. MongoDB počeo je da eksperimentiše sa "Full-Text Search" koristeći "Text Indexes". Full-Text Search je postao sastavni deo MongoDB-a i predstavlja tehniku pretraživanja "full-text database" na osnovu kriterijuma koji je specificirao korisnik. Sličan način rada koji viđamo kada koristimo Google pretraživač, nakon kucanja željene reči/fraze dobijemo rezultat sortiran na osnovu nekog rangiranja.

Određeni pojmovi sa kojima treba biti upoznat a da su vezani za full-text search su:

  • Stop Words - "nebitne" reči koje će biti izbačene iz teksta. (i, a, u, na itd ... )
  • Stemming - proces skraćenja reči na njihovu osnovu. ( reči kao zubar, zubarski, zubni imaju osnovu zub)
  • Scoring - rankiranje na osnovu kojeg se meri koji je rezultat pretrage najrelevantniji.

Pri korišćenju MongoDB full-text search-a, treba se definisati text index koji može biti polje dokumenta koje je string ili niz stringova. Kada se određeno polje izabere za text index, MongoDB ga "tokenizuje" i "stems-uje" (određuje koren reči) i ređa ih po tome.

Za potrebe sledećih zadataka potrebno je da import-ujemo novi json fajl (filmovi.json)

Fajl fimovi.json skinuti sa github naloga https://github.com/elab-office/mongoDB/tree/master/json

Djordje:~/ $ mongoimport --db filmovi --drop --collection film --file ~/desktop/filmovi.json --jsonArray
2017-05-09T14:25:45.050+0200    connected to: localhost
2017-05-09T14:25:45.051+0200    dropping: filmovi.film
2017-05-09T14:25:45.100+0200    imported 5 documents

Zadatak 45 - Unutar kolekcije film baze podataka filmovi, za text index postaviti nazive filmova i naći sve filmove u kojima se spominje reč "grad", i sortirati ih po "textScore" vrednostima.

Text index se postavlja korišćenjem već poznate createIndex() metode, samo što se umesto brojeva 1 ili -1 stavlja vrednost "text".
Pretraga se obavlja korišćenjem $text . Kako bi znali nivo relevantnosti rezultata može se koristii $meta: "textScore".

Rešenje

> use filmovi
switched to db filmovi
> db.film.createIndex({"naziv": "text"})
{
    "createdCollectionAutomatically" : false,
    "numIndexesBefore" : 1,
    "numIndexesAfter" : 2,
    "ok" : 1
}
> db.film.find({$text: {$search: "grad"}}, {score: {$meta: "textScore"}}).sort({score: {$meta: "textScore"}}).pretty()
{
    "_id" : ObjectId("5911bb630423845e266abc63"),
    "naziv" : "Izgubljeni grad Z",
    "opis" : "Film koji predstavlja istinit dogadjaj, ciji je glavmi lik britanski istrazivac Percival Fawcett, koji je nestao istrazivajuci misteriozni grad unutar Amazona davne 1920.te",
    "ocena" : 7.1,
    "glumci" : [
        "Charlie Hunnam",
        "Robert Pattinson",
        "Sienna Miller",
        "Tom Holland"
    ],
    "godina" : 2016,
    "score" : 0.6666666666666666
}

Dodatak

Stemming reči se obavlja ukoliko MongoDB prepozna reč. MongoDB podržava ovu listu jezika. Nažalost, srpski nije na toj list


Zadatak 46 - Unutar kolekcije film baze podataka filmovi, za text index postaviti nazive filmova i njihove opise i naći sve filmove u kojima se spominje reč "avanture", i sortirati ih po "textScore" vrednostima.

Moguće je imati samo jedan "text index". Tako da je u našem slučaju potrebno prvo da obrišemo stari (koristeći već poznatu dropIndex() metodu) i zatim napraviti novi.

Rešenje

> use filmovi
switched to db filmovi
> db.film.dropIndex("naziv_text")
{ "nIndexesWas" : 2, "ok" : 1 }
> db.film.createIndex({"naziv":"text", "opis":"text"})
{
    "createdCollectionAutomatically" : false,
    "numIndexesBefore" : 1,
    "numIndexesAfter" : 2,
    "ok" : 1
}
> db.film.find({$text: {$search: "avanture"}}, {score: {$meta: "textScore"}}).sort({score: {$meta: "textScore"}}).pretty()
{
    "_id" : ObjectId("5911c5610423845e266abc6f"),
    "naziv" : "Tajne avanture kucnih ljubimaca",
    "opis" : "Miran zivot terijera zvanog Max biva poremecen kada njegov vlasnik uzima lutalicu koju Max ne voli uopste.",
    "ocena" : 6.6,
    "glumci" : [
        "Louis C.K.",
        "Eric Stonestreet",
        "Kevin Hart",
        "Lake Bell"
    ],
    "godina" : 2015,
    "score" : 0.625
}
{
    "_id" : ObjectId("5911c5610423845e266abc6d"),
    "naziv" : "Colossal",
    "opis" : "Gloria je devojka bez posla koja voli avanture i da partija i koja mora napustiti svoj zivot u New York-u i vratiti se kuci. Kada se pojavi vest o ogromnom stvorenju koje unistava grad Seoul, na cudan nacin shvati da je ona nekako povezana sa tim fenomenom",
    "ocena" : 6.5,
    "glumci" : [
        "Anne Hathaway",
        "Jason Sudeikis",
        "Austin Stowell",
        "Tim Blake Nelson"
    ],
    "godina" : 2016,
    "score" : 0.5111111111111111
}

Zadatak 47 - Unutar kolekcije film baze podataka filmovi, za text index postaviti cele dokumente i naći sve filmove u kojima glumi "Emma Stone"

U nekim slučajevima je potrebno da se vrši pretraga nad celim dokumentima. Tada se koristi "Wildcard Indexing", umesto naziva polja dokumenta koristi se $**.

Rešenje

> use filmovi
switched to db filmovi
> db.film.dropIndex("naziv_text_opis_text")
{ "nIndexesWas" : 2, "ok" : 1 }
> db.film.createIndex({"$**":"text"})
{
    "createdCollectionAutomatically" : false,
    "numIndexesBefore" : 1,
    "numIndexesAfter" : 2,
    "ok" : 1
}
> db.film.find({$text: {$search: "Emma Stone"}}, {score: {$meta: "textScore"}}).sort({score: {$meta: "textScore"}}).pretty()
{
    "_id" : ObjectId("5911c5610423845e266abc6e"),
    "naziv" : "La La Land",
    "opis" : "Prica o zaljubljenom dzez pijanista i slavnoj glumicu u Los Angeles-u.",
    "ocena" : 8.3,
    "glumci" : [
        "Ryan Gosling",
        "Emma Stone",
        "Rosemarie DeWitt",
        "J.K. Simmons"
    ],
    "godina" : 2016,
    "score" : 1.5
}

Dodatak

Wildcard indeksi mogu da obore performanse pretrage, pogotovo kada je data koja se pretražuje velika, iz tog razloga, jako je bitno da se indeksirani dokumenti dobro isplaniraju.

results matching ""

    No results matching ""