back to basics, webinar 4: indicizzazione avanzata, indici testuali e geospaziali

Post on 14-Apr-2017

310 Views

Category:

Data & Analytics

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

MongoDB Europe 2016Old Billingsgate, London

15 November

mongodb.com/europe

Massimo BrignoliPrincipal Solution Architect, EMEAmassimo@mongodb.com@massimobrignoli

Back to Basics 2016 : Webinar 4

Indicizzazione AvanzataIndici Geografici e Testuali

Riassunto• Webinar 1 – Introduzione a NoSQL

– I vari tipi di database NoSQL– Che tipo di database è MongoDB

• Webinar 2 – La nostra prima applicazione– Creare database e collection– Operazioni CRUD– Indici e Explain

• Webinar 3 – Schema Design– Schema Dinamico– Approcci all’incapsulamento– Esempi

Indexing• Un modo efficiente per ricercare dei dati usando il loro

valore• Evitare scansione completa di collection

I Database Tradizionali Usano BTREE• … E anche MongoDB...

Ricerche, Inserimenti, Cancellazioni in O(Log(n))

Creazione di un Indice Semplicedb.coll.createIndex( { fieldName : <Direction> } )

Nome del Database

Nome della Collection

Comando

Nome del campo(i) da indicizzare

Ascendente: 1 Discendente: -1

Altri due tipi di Indice• Indice Full Text– Permette la ricerca all’interno del testo di un campo (Lucene,

Solr e Elastic Search)• Indice Geospaziale– Permette la ricerca per posizione geografica (e.g. tutte le

persone vicino a me)• Questi indici non usano Btree

Indici Full Text• Un “inverted index” di tutte le parole contenute in un singolo

campo (si può creare solo un indice full text per ogni collection)

{ “comment” : “I think your blog post is very interesting and informative. I hope you will post more info like this in the future” }>> db.posts.createIndex( { “comments” : “text” } )

MongoDB Enterprise > db.posts.find( { $text: { $search : "info" }} ){ "_id" : ObjectId(“…"), "comment" : "I think your blog post is very interesting and informative. I hope you will post more info like this in the future" }MongoDB Enterprise >

Parametri dell’IndiceMongoDB Enterprise > db.posts.getIndexes()...

{"v" : 1,"key" : {

"_fts" : "text","_ftsx" : 1

},"name" : "comment_text","ns" : "test.posts","weights" : {

"comment" : 1},"default_language" : "english","language_override" : "language","textIndexVersion" : 3

}

Nel Log del ServerI INDEX [conn275] build index on: test.posts properties: { v: 1, key: { _fts: "text", _ftsx: 1 }, name: "comment_text", ns: "test.posts", weights: { comment: 1 }, default_language: "english", language_override: "language", textIndexVersion: 3 }}I INDEX [conn275] building index using bulk methodI INDEX [conn275] build index done. scanned 3 total records. 0 secs

Alcuni Esempi in Dettaglio>> db.posts.insert( { "comment" : "Red yellow orange green" } )>> db.posts.insert( { "comment" : "Pink purple blue" } )>> db.posts.insert( { "comment" : "Red Pink" } )

>> db.posts.find( { "$text" : { "$search" : "Red" }} ){ "_id" : ObjectId(“…”), "comment" : "Red yellow orange green" }{ "_id" : ObjectId(  »…"), "comment" : "Red Pink" }>> db.posts.find( { "$text" : { "$search" : "Red Green" }} ){ "_id" : ObjectId(« …"), "comment" : "Red Pink" }{ "_id" : ObjectId(« …"), "comment" : "Red yellow orange green" }>> db.posts.find( { "$text" : { "$search" : "red" }} ) # <- Case Insensitve{ "_id" : ObjectId(“…"), "comment" : "Red yellow orange green" }{ "_id" : ObjectId(«…”), "comment" : "Red Pink" }>>

Usare I Pesi• Possiamo assegnare pesi diversi ai vari campi

nell’indice testuale• Ad esempio posso voler favorire i tag rispetto ai

commenti• Quindi incremento il peso del campo tags

>> db.blog.createIndex( { comment: "text", tags : "text” }, { weights: { comment: 5, tags : 10 }} )• Ora la ricerca favorirà il campo tags

$textscore• Possiamo usare il lo score risultante per ordinare i

risultati

>> db.posts.find( { "$text" : { "$search" : "Red" }}, { score: { $meta: "textScore" }} ).sort( { score: { $meta: "textScore" } } )

{ "_id" : …, "comment" : "hello", "tags" : "Red green orange", "score" : 6.666666666666666 }{ "_id" : …, "comment" : "Red Pink", "score" : 3.75 }{ "_id" : …, "comment" : "Red yellow orange green", "score" : 3.125 }>>

Altri Parametri• Language : Scegli la lingua che vuoi usare in ricerca, ad

esempio:– $language : Spanish

• Abilita la ricerca case sensitive– $caseSensitive : True (default false)

• Supporta i caratteri accentati (diacritic sensitive search ad esempio café è diverso da cafe )– $diacriticSensitive : True (default false)

Indici Geospaziali

Indici Geospaziali• MongoDB supporta indici sferici 2D• Permette ad un utente di rappresentazione una

posizione sulla terra (approssimata ad una sfera)• Le coordinate sono memorizzate in un formato

GeoJSON• L’indice geospaziale supporta un sottoinsieme

delle operazioni GeoJSON• L’indice è basato su una rappresentazione

QuadTree • L’indice è basato sullo standard WGS 84

Coordinate• Le coordinate sono rappresentate con longitudine e

latitudine• longitudine– Misurata dal meridiano di Greenwich a Londra (0 gradi). Le

posizione ad est arrivano fino a 180 gradi, mentre quelle ad ovest si esprimono con un numero negativo

• Latitudine– Misurata dall’equatore verso nord e sud (da 0 a 90 nord, da 0 a -

90 sud)• Le coordinate in MongoDB sono memorizzate con

l’ordine longitutine/latitudine• Coordinate in Google sono memorizzate invertite

Versioni dell’Indice 2DSphere• Versione 1 : prima di MongoDB 2.4• Versione 2 : da MongoDB 2.6 in poi• Versione 3 : da MongoDB 3.2 in poi• Parlaremo solo della Versione 3 in questo webinar

Creare un Indice 2DSpheredb.collection.createIndex ( { <location field> : "2dsphere" } )

• Il campo di posizione deve contenere coordinate oppure una struttura dati GeoJSON

Esempio

>> db.test.createIndex( { loc : "2dsphere" } ){

"createdCollectionAutomatically" : false,"numIndexesBefore" : 1,"numIndexesAfter" : 2,"ok" : 1

}

Output>> db.test.getIndexes()[

{"v" : 1,"key" : {

"loc" : "2dsphere"},"name" : "loc_2dsphere","ns" : "geo.test","2dsphereIndexVersion" : 3

}]>>

Usiamo una Semplice Base Dati per Sperimentare le Query Geografiche

• Cerchiamo i ristoranti a Manhattan• Scarichiamo I dati di due collection

– https://raw.githubusercontent.com/mongodb/docs-assets/geospatial/neighborhoods.json– https://raw.githubusercontent.com/mongodb/docs-assets/geospatial/restaurants.json

• Importiamole dentro MongoDB invocando da shell– mongoimport –c neighborhoods –d geo neighborhoods.json– mongoimport –c restaurants –d geo restaurants.json

Documento dei QuartieriMongoDB Enterprise > db.neighborhoods.findOne(){

"_id" : ObjectId("55cb9c666c522cafdb053a1a"),"geometry" : {

"coordinates" : [[

[-73.94193078816193,40.70072523469547

], ...

[-73.94409591260093,40.69897295461309

], ]

"type" : "Polygon"},"name" : "Bedford"

}

Documento dei RistorantiMongoDB Enterprise > db.restaurants.findOne(){

"_id" : ObjectId("55cba2476c522cafdb053adf"),"location" : {"coordinates" : [-73.98241999999999,40.579505],"type" : "Point"},"name" : "Riviera Caterer"

}MongoDB Enterprise >

Per visualizzarlo su google maps

ricordatevi di invertire le coordinate

Aggiungiamo gli IndiciMongoDB Enterprise > db.restaurants.createIndex({ location: "2dsphere" }){

"createdCollectionAutomatically" : false,"numIndexesBefore" : 1,"numIndexesAfter" : 2,"ok" : 1

}MongoDB Enterprise > db.neighborhoods.createIndex({ geometry: "2dsphere" }){

"createdCollectionAutomatically" : false,"numIndexesBefore" : 1,"numIndexesAfter" : 2,"ok" : 1

}MongoDB Enterprise >

Usiamo $geoIntersects per trovare I Quartieri

• Assumiamo di essere a -73.93414657, 40.82302903• In quale quartiere siamo? Usiamo $geoIntersects

db.neighborhoods.findOne({ geometry: { $geoIntersects: { $geometry: { type: "Point", coordinates: [ -73.93414657, 40.82302903 ]}}}})

Risultato{

"geometry" : { ”coordinates" : [

[-73.9338307684026,40.81959665747723

], ...

[-73.93383000695911,40.81949109558767

] ]

"type" : "Polygon"},"name" : "Central Harlem North-Polo Grounds"

}

Troviamo I Ristoranti a 350mdb.restaurants.find({ location: { $geoWithin: { $centerSphere: [ [ -73.93414657, 40.82302903 ], 0.35 / 6378.1 ] } } })

Distanza in KM Dividete per il raggio

della terra per convertire in radianti

Risultati – (Projected){ "name" : "Gotham Stadium Tennis Center Cafe" }{ "name" : "Chuck E. Cheese'S" }{ "name" : "Red Star Chinese Restaurant" }{ "name" : "Tia Melli'S Latin Kitchen" }{ "name" : "Domino'S Pizza" }

• Senza projection

{ "_id" : ObjectId("55cba2476c522cafdb0550aa"), "location" : { "coordinates" : [ -73.93795159999999, 40.823376 ], "type" : "Point" }, "name" : "Domino'S Pizza" }

Riassunto delle Operazioni• $geoIntersect: Trova aree o punti che si sovrappongono

o sono adiaicenti• $geoWithin: Trova aree che contengono un punto• $geoNear: Restituisce le posizioni geografiche in ordine di

distanza crescente

Riassunto• Text Indexes : Ricerca full text su tutti I campi testo di

una collection• Geospatial Indexes : Ricerca per posizione, per

intersezione o per distanza a partire da un punto

Prossimo Webinar : Introduzione ad Aggregation Framework

• Consente agli sviluppatori di– Modificare, trasformare ed estrarre dati.– Applicare funzioni analitiche standard, dai totali e le medie fino

alla deviazione standard.• Lo vedrete in azione su un set di dati pubblici.

19 Luglio 2016, 11:00 CET.

top related