MongoDBEurope2016
Old Billingsgate, London
15th November
Use my code emmanueldeletang20 for 20% off tickets
mongodb.com/europe
Back to Basics 2016 : Webinar 4
Advanced Indexing –
Text and Geospatial Indexes
Emmanuel DELETANG
Emmanuel.deletang@mongodb.com
Senior Solutions Architect
V1.0
3
Recap
• Webinar 1 – Introduction to NoSQL
– Les différentes type de base de données No SQL
– Mongodb est quel type de base de données.
• Webinar 2 – Ma première application avec MongoDB
– Créer une base et collections
– CRUD opérations
– Indexations et plan d’execution
• Webinar 3 – Schéma Design
– Schéma dynamique
– Approches embarqué
– Exemples
4
Indexing
• Une voie évidente pour accède a la valeur de la données
• Eviter les “Table Scan”
1 2 3 4 5 6 7
5
Les bases de données Traditionnel utilise Btrees
• … Et pour MongoDB
6
Requête , insert , suppressions ,O(Log(n) Time
7
Cree un index
db.coll.createIndex( { fieldName : <Direction> } )
Base de donnees
collections
Command
Nom du champs a indexes
Ascending : 1
Descending : -1
8
Autres index
• Full Text Index
– Permet de rechercher dans le texte d'un champ ( Lucene , Solr et
Recherche élastique )
• Geospatial Index
– Permet de rechercher par emplacement ( par exemple les gens près de
moi )
– Ce ne sont pas des index Btrees
9
Full Text Indexes
•
Un " index inversé " sur tous les mots à l'intérieur d'un champ unique (un seul index de texte
par 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 >
10
Results
MongoDB 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
}
11
Sur le Server
I 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 method
I INDEX [conn275] build index done. scanned 3 total records. 0 secs
12
Quelques details
>> 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" }
>>
13
Utilisation du poids
• Nous pouvons assigner des poids différents aux champs(domaines)
différents dans l'index(indice) de texte
• Par exemple. Je veux favoriser des étiquettes sur des commentaires dans la
recherche
• Donc j'augmente le poids pour le champ(domaine) d'étiquettes
>> db.blog.createIndex( { comment: "text",
tags : "text” },
{ weights: { comment: 5,
tags : 10 }} )
• Maintenant les recherches favoriseront des étiquettes
14
$textscore
• Nous pouvons vouloir favoriser des résultats avec des poids plus hauts,
ainsi:
>> 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 }
>>
15
Autre parametres
• Langue : Choisissez la langue dans laquelle vous voulez
fouiller(rechercher) par exemple.
• $language : Spanish
• Support de la recherche “case sensitive”
– $caseSensitive : True (default false)
• Le support des caractères accentués (la recherche sensible
diacritique par exemple « café » est different de « cafe »)
• $diacriticSensitive : True (default false)
Geospatial Indexes
17
Geospatial Indexes
• MongoDB supporte des index de Sphère 2D
• Permet à un utilisateur de représenter l'emplacement sur la terre (qui est une
sphère)
• Les Coordonnées sont stockées à GeoJSON formatent
• l'index Géospatial soutient le sous-ensemble des opérations de GeoJSON
• l'index est basé sur une représentation de QuadTree
• l'Index est basé sur la norme WGS 84
18
coordonnées
• Les coordonnées sont représentées par la longitude, latitude
• la longitude
– Mesurée du méridien de Greenwich à Londres (0 degrés) l'est (jusqu'à
180 degrés)
– Pour l'ouest nous spécifions l'emplacements comme négatif
• La latitude
– Mesurée du nord d'équateur et le sud (0 à 90 nord, 0 à-90 sud)
• les Coordonnées dans MongoDB sont stockées sur l’ordre
Longitude/Latitude
• les Coordonnées dans Google sont stockées dans l’ordre Latitude/Longitude
19
2DSphere Versions
• Deux versions active d’index 2dSphere
• Version 1: jusqu'à MongoDB 2.4
• Version 2: de MongoDB 2.6 en avant la V 3:0 MongoDB
• Version 3: depuis MongoDB 3.2
• Nous parlerons seulement de la Version 3 dans ce
webinaire
20
Cree un index 2dSphere
db.collection.createIndex
( { <location field> : "2dsphere" } )
• Le champ de localisation doit être la coordonnée ou des données GeoJSON
21
Example
>> db.test.createIndex( { loc : "2dsphere" } )
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
22
Output
>> db.test.getIndexes()
[
{
"v" : 1,
"key" : {
"loc" : "2dsphere"
},
"name" : "loc_2dsphere",
"ns" : "geo.test",
"2dsphereIndexVersion" : 3
}
]
>>
23
Utilisez un Ensemble de données Simple pour examiner des
Questions de Geo
• Recherche de restaurants au Manhattan
• Utilisation de deux exemples
– https://raw.githubusercontent.com/mongodb/docs-assets/geospatial/neighborhoods.json
– https://raw.githubusercontent.com/mongodb/docs-assets/geospatial/restaurants.json
• Importer dans mongoDB
– mongoimport –c neighborhoods –d geo neighborhoods.json
– mongoimport –c restaurants –d geo restaurants.json
24
Neighborhood Document
MongoDB Enterprise > db.neighborhoods.findOne()
{
"_id" : ObjectId("55cb9c666c522cafdb053a1a"),
"geometry" : {
"coordinates" : [
[
[
-73.94193078816193,
40.70072523469547
],
...
[
-73.94409591260093,
40.69897295461309
],
]
"type" : "Polygon"
},
"name" : "Bedford"
}
25
Restaurant Document
MongoDB Enterprise > db.restaurants.findOne()
{
"_id" : ObjectId("55cba2476c522cafdb053adf"),
"location" : {
"coordinates" : [
-73.98241999999999,
40.579505
],
"type" : "Point"
},
"name" : "Riviera Caterer"
}
MongoDB Enterprise >
You can type this into
google maps but
remember to reverse the
coordinate order
26
Ajout Indexes
MongoDB 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 >
27
utilisez $geoIntersects pour trouver vos voisins
• Suppose que nous sommes a : -73.93414657, 40.82302903
• Dans quel quartier sommes-nous? Utilisons $geoIntersects
db.neighborhoods.findOne({ geometry:
{ $geoIntersects:
{ $geometry:
{ type: "Point",
coordinates:
[ -73.93414657,
40.82302903 ]}}}})
28
Resultats
{
"geometry" : {
”coordinates" : [
[
-73.9338307684026,
40.81959665747723
],
...
[
-73.93383000695911,
40.81949109558767
]
]
"type" : "Polygon"
},
"name" : "Central Harlem North-Polo Grounds"
}
29
Trouvez un restautant a moins de 0.35 km
db.restaurants.find({ location:
{ $geoWithin: { $centerSphere:
[ [ -73.93414657, 40.82302903 ], 5 / 6,378.1 ] }
} })
Distance in km
Divide by radius of earth
to convert to radians
30
Results – (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" }
• Without projection
{ "_id" : ObjectId("55cba2476c522cafdb0550aa"),
"location" : { "coordinates" : [ -73.93795159999999, 40.823376 ],
"type" : "Point" },
"name" : "Domino'S Pizza" }
31
Résumer des operateurs
• $geoIntersect: trouver un point a cote de …
• $geoWithin: trouver une aire par rapport a un point spécifique
$geoNear: Retourne une localisation par rapport a une
information a cote de
32
Résumer
• Text Indexes
• Geospatial Indexes
Webinaire 4 de la série Retour aux fondamentaux : Indexation avancée, index de texte et géospatiaux

Webinaire 4 de la série Retour aux fondamentaux : Indexation avancée, index de texte et géospatiaux

  • 1.
    MongoDBEurope2016 Old Billingsgate, London 15thNovember Use my code emmanueldeletang20 for 20% off tickets mongodb.com/europe
  • 2.
    Back to Basics2016 : Webinar 4 Advanced Indexing – Text and Geospatial Indexes Emmanuel DELETANG Emmanuel.deletang@mongodb.com Senior Solutions Architect V1.0
  • 3.
    3 Recap • Webinar 1– Introduction to NoSQL – Les différentes type de base de données No SQL – Mongodb est quel type de base de données. • Webinar 2 – Ma première application avec MongoDB – Créer une base et collections – CRUD opérations – Indexations et plan d’execution • Webinar 3 – Schéma Design – Schéma dynamique – Approches embarqué – Exemples
  • 4.
    4 Indexing • Une voieévidente pour accède a la valeur de la données • Eviter les “Table Scan” 1 2 3 4 5 6 7
  • 5.
    5 Les bases dedonnées Traditionnel utilise Btrees • … Et pour MongoDB
  • 6.
    6 Requête , insert, suppressions ,O(Log(n) Time
  • 7.
    7 Cree un index db.coll.createIndex({ fieldName : <Direction> } ) Base de donnees collections Command Nom du champs a indexes Ascending : 1 Descending : -1
  • 8.
    8 Autres index • FullText Index – Permet de rechercher dans le texte d'un champ ( Lucene , Solr et Recherche élastique ) • Geospatial Index – Permet de rechercher par emplacement ( par exemple les gens près de moi ) – Ce ne sont pas des index Btrees
  • 9.
    9 Full Text Indexes • Un" index inversé " sur tous les mots à l'intérieur d'un champ unique (un seul index de texte par 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 >
  • 10.
    10 Results MongoDB 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 }
  • 11.
    11 Sur le Server IINDEX [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 method I INDEX [conn275] build index done. scanned 3 total records. 0 secs
  • 12.
    12 Quelques details >> 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" } >>
  • 13.
    13 Utilisation du poids •Nous pouvons assigner des poids différents aux champs(domaines) différents dans l'index(indice) de texte • Par exemple. Je veux favoriser des étiquettes sur des commentaires dans la recherche • Donc j'augmente le poids pour le champ(domaine) d'étiquettes >> db.blog.createIndex( { comment: "text", tags : "text” }, { weights: { comment: 5, tags : 10 }} ) • Maintenant les recherches favoriseront des étiquettes
  • 14.
    14 $textscore • Nous pouvonsvouloir favoriser des résultats avec des poids plus hauts, ainsi: >> 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 } >>
  • 15.
    15 Autre parametres • Langue: Choisissez la langue dans laquelle vous voulez fouiller(rechercher) par exemple. • $language : Spanish • Support de la recherche “case sensitive” – $caseSensitive : True (default false) • Le support des caractères accentués (la recherche sensible diacritique par exemple « café » est different de « cafe ») • $diacriticSensitive : True (default false)
  • 16.
  • 17.
    17 Geospatial Indexes • MongoDBsupporte des index de Sphère 2D • Permet à un utilisateur de représenter l'emplacement sur la terre (qui est une sphère) • Les Coordonnées sont stockées à GeoJSON formatent • l'index Géospatial soutient le sous-ensemble des opérations de GeoJSON • l'index est basé sur une représentation de QuadTree • l'Index est basé sur la norme WGS 84
  • 18.
    18 coordonnées • Les coordonnéessont représentées par la longitude, latitude • la longitude – Mesurée du méridien de Greenwich à Londres (0 degrés) l'est (jusqu'à 180 degrés) – Pour l'ouest nous spécifions l'emplacements comme négatif • La latitude – Mesurée du nord d'équateur et le sud (0 à 90 nord, 0 à-90 sud) • les Coordonnées dans MongoDB sont stockées sur l’ordre Longitude/Latitude • les Coordonnées dans Google sont stockées dans l’ordre Latitude/Longitude
  • 19.
    19 2DSphere Versions • Deuxversions active d’index 2dSphere • Version 1: jusqu'à MongoDB 2.4 • Version 2: de MongoDB 2.6 en avant la V 3:0 MongoDB • Version 3: depuis MongoDB 3.2 • Nous parlerons seulement de la Version 3 dans ce webinaire
  • 20.
    20 Cree un index2dSphere db.collection.createIndex ( { <location field> : "2dsphere" } ) • Le champ de localisation doit être la coordonnée ou des données GeoJSON
  • 21.
    21 Example >> db.test.createIndex( {loc : "2dsphere" } ) { "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 }
  • 22.
    22 Output >> db.test.getIndexes() [ { "v" :1, "key" : { "loc" : "2dsphere" }, "name" : "loc_2dsphere", "ns" : "geo.test", "2dsphereIndexVersion" : 3 } ] >>
  • 23.
    23 Utilisez un Ensemblede données Simple pour examiner des Questions de Geo • Recherche de restaurants au Manhattan • Utilisation de deux exemples – https://raw.githubusercontent.com/mongodb/docs-assets/geospatial/neighborhoods.json – https://raw.githubusercontent.com/mongodb/docs-assets/geospatial/restaurants.json • Importer dans mongoDB – mongoimport –c neighborhoods –d geo neighborhoods.json – mongoimport –c restaurants –d geo restaurants.json
  • 24.
    24 Neighborhood Document MongoDB Enterprise> db.neighborhoods.findOne() { "_id" : ObjectId("55cb9c666c522cafdb053a1a"), "geometry" : { "coordinates" : [ [ [ -73.94193078816193, 40.70072523469547 ], ... [ -73.94409591260093, 40.69897295461309 ], ] "type" : "Polygon" }, "name" : "Bedford" }
  • 25.
    25 Restaurant Document MongoDB Enterprise> db.restaurants.findOne() { "_id" : ObjectId("55cba2476c522cafdb053adf"), "location" : { "coordinates" : [ -73.98241999999999, 40.579505 ], "type" : "Point" }, "name" : "Riviera Caterer" } MongoDB Enterprise > You can type this into google maps but remember to reverse the coordinate order
  • 26.
    26 Ajout Indexes MongoDB 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 >
  • 27.
    27 utilisez $geoIntersects pourtrouver vos voisins • Suppose que nous sommes a : -73.93414657, 40.82302903 • Dans quel quartier sommes-nous? Utilisons $geoIntersects db.neighborhoods.findOne({ geometry: { $geoIntersects: { $geometry: { type: "Point", coordinates: [ -73.93414657, 40.82302903 ]}}}})
  • 28.
    28 Resultats { "geometry" : { ”coordinates": [ [ -73.9338307684026, 40.81959665747723 ], ... [ -73.93383000695911, 40.81949109558767 ] ] "type" : "Polygon" }, "name" : "Central Harlem North-Polo Grounds" }
  • 29.
    29 Trouvez un restautanta moins de 0.35 km db.restaurants.find({ location: { $geoWithin: { $centerSphere: [ [ -73.93414657, 40.82302903 ], 5 / 6,378.1 ] } } }) Distance in km Divide by radius of earth to convert to radians
  • 30.
    30 Results – (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" } • Without projection { "_id" : ObjectId("55cba2476c522cafdb0550aa"), "location" : { "coordinates" : [ -73.93795159999999, 40.823376 ], "type" : "Point" }, "name" : "Domino'S Pizza" }
  • 31.
    31 Résumer des operateurs •$geoIntersect: trouver un point a cote de … • $geoWithin: trouver une aire par rapport a un point spécifique $geoNear: Retourne une localisation par rapport a une information a cote de
  • 32.

Notes de l'éditeur

  • #3 Who I am, how long have I been at MongoDB.
  • #6 Each item in a Btree node points to a sub-tree containing elements below its key value. Insertions require a read before a write. Writes that split nodes are expensive.
  • #7 Effectively the depth of the tree.
  • #20 Production release numbering.