2014 04-09-fr - app dev series - session 4 - indexing

Preview:

DESCRIPTION

 

Citation preview

Tugdual Grall (@tgrall) Alain Hélaïli (@AlainHelaili)

#MongoDBBasics @MongoDB

Construire une application avec MongoDBStratégies et options d’indexation

2

• Résumé des épisodes précédents

• Fondamentaux de l’indexation– Types d’index dans notre application– Compound index– Covered index

• Evaluation / Tuning– Explain plan– Database profiler

• Geospatial

• Text Search

Agenda

3

VERSION 2.6

4

• Virtual Genius Bar– Utilisez la fenêtre de chat

– Tug & Alain dispo pendant, et après…

• MUGs à Paris, Toulouse, Bordeaux, Rennes, Lyon

• Groupes LinkedIn « MongoDB France » et « MongoDB » sur Viadeo

Q & A

@tgrall, tug@mongodb.com - @AlainHelaili, alain.helaili@mongodb.cm

Résumé des épisodes précédents….

6

Inserts

• ObjectId()

• _id

• Durability

• WriteConcerns

• For updates too

>db.articles.insert({'text': 'Article

content…’, 'date' : ISODate(...), 'title' : ’Intro to MongoDB’, 'author' : 'Dan Roberts’, 'tags' : [

'mongodb',

'database', 'nosql’

]});

options w: MAJORITY, j : true

7

Queries

• Comparison operators

• projections

• cursors

operators$gt, $gte, $in, $lt,

$lte, $ne, $nin>var cursor = db.articles.find( { ’author' : ’Dan Roberts’ } , {‘_id’:0, ‘title’:1})

>cursor.hasNext()true

>cursor.next(){ "title" : "Intro to MongoDB" }

8

Updates

• Manipulate documents efficiently

• Bucketing

• Pre Aggregated reports

• In place updates

operators

$each, $slice, $sort, $inc, $push$inc, $rename, $setOnInsert, $set,

$unset, $max, $min$, $addToSet, $pop, $pullAll, $pull,

$pushAll, $push$each, $slice, $sort

>db.comments.update(

{‘c’: {‘$lt’:10}}, {

‘$inc’ : {c:1},

'$push' : {

'comments' : ‘Excellent’}},{ upsert : true }

)

Fondamentaux de l’indexation

10

• Plus important réglage dans la DB en matière de performance (le schéma n’est pas un réglage).– L’efficacité des index doit être examinée très tôt– Eviter les duplications

– .// index on author (ascending)>db.articles.ensureIndex( { author : 1 } )

// index on title (descending)>db.articles.ensureIndex( { title: -1 } )

// index on arrays of values – multi key index>db.articles.ensureIndex( { tags : 1 } )

Fondamentaux

11

• Indexation des sous documents– Utilisation de la dot-notation

Sous documents

{‘_id’ : ObjectId(..),

‘article_id’ : ObjectId(..), ‘section’ : ‘schema’,

‘date’ : ISODate(..),‘daily’: { ‘views’ : 45,

‘comments’ : 150 } ‘hours’ : { 0 : { ‘views’ : 10 }, 1 : { ‘views’ : 2 }, … 23 : { ‘views’ : 14,

‘comments’ : 10 } }}

>db.interactions.ensureIndex(

{ “daily.comments” : 1}

}

>db.interactions.find(

{“daily.comments” : { $gte : 150} } ,

{ _id:0, “daily.comments” : 1 } )

12

Index = Btree, O(log(n))

13

• Index utilisant de multiples attributs

Index composé (compound)

> db.articles.ensureIndex( { author : 1, tags : 1 } )

> db.articles.find( { author : ‘Dan Roberts’, tags : ‘MongoDB’} )//et aussi> db.articles.find( { author : ‘Dan Roberts’ } )

// Cet index est inutile> db.articles.ensureIndex( { author : 1 } )

14

Index multiclés (multikey)

• Index utilisant de multiples valeurs

{ "_id" : ObjectId("..."), .. ,"tags" : [ "weather", "hot", "record", "april" ]}

> db.articles.ensureIndex( { tags : 1 } )

> db.articles.find( {tags : ‘record’} )

15

• Le tri n’a pas d’importance pour les index simples– Lecture dans les deux sens du BTree

• { attribute: 1 } ou { attribute: -1 }

• Le tri est important pour les ‘compound indexes’– Requête sur auteur, et tri par date

Ordre de tri

// index sur author croissant et décroissant sur date

>db.articles.ensureIndex( { ‘author’ : 1, ‘date’ -1 } )

16

• Retourne uniquement des données comprises dans l’index– Pas d’utilisation du fichier DB– Performance optimale– Valide pour les index composés

• Invoke with a projection

Requête couverte (covered)

> db.users.ensureIndex( { user : 1, password :1 } )

> db.user.find({user:"danr"}, {_id:0, password:1})

{ "password" : ”*********" }

Tip: utiliser les projections au maximum pour limiter les quantités de données à acheminer vers le client

17

• TTL– db.address.ensureIndex( { "createdAt": 1 }, { expireAfterSeconds: 3600 } )

– db.adress.ensureIndex( { "expireAt": 1 }, { expireAfterSeconds: 0 } )

• Unique– db.address.ensureIndex( { "user_id": 1 }, { unique: true } )

• Sparse– db.address.ensureIndex( { ”etage": 1 }, { sparse: true } )

• Intersection

Autres concepts

18

• Permet d’évaluer l’efficactié des requêtes et index– Quels index ont été utilisés… ou pas– Combien de documents ou objets ont été scannés– Utilisable via la console ou en code

Explication du plan d’exécution

//To view via the console> db.articles.find({author:'Dan Roberts'}).sort({date:-1}).explain()

19

Sortie de la commande explain

{"cursor" : "BtreeCursor

author_1_date_-1","isMultiKey" : false,"n" : 1,"nscannedObjects" : 1,"nscanned" : 1,"nscannedObjectsAllPlans" : 1,"nscannedAllPlans" : 1,"scanAndOrder" : false,"indexOnly" : false,"nYields" : 0,"nChunkSkips" : 0,"millis" : 0,"indexBounds" :….

Autres types:

• BasicCursor• Full collection scan

• BtreeCursor• GeoSearchCursor• Complex Plan• TextCursor

20

• Permet de logger les requêtes lentes– Au-delà d’un temps d’exécution (défaut 100ms)– Toutes les requêtes également

Profiler

//Enable database profiler on the console, 0=off 1=slow 2=all> db.setProfilingLevel(1, 100){ "was" : 0, "slowms" : 100, "ok" : 1 }

//View profile with > show profile

//or>db.system.profile.find().pretty()

21

Sortie du profiler

{"op" : "query","ns" : "test.articles","query" : {

"query" : {"author" : "Dan Roberts"

},"orderby" : {

"date" : -1}

},"ntoreturn" : 0,"ntoskip" : 0,"nscanned" : 1,"nreturned" : 1,

……

Index Geo Spatiaux

23

• Index sur des champs geospatiaux– Utilise le format GeoJSON– Geometrie sur plans et spheres

2d et 2dSphere

//GeoJSON object structure for indexing

"location" : { "type" : "Point", "coordinates" : [ -0.128, 51.507 ] }

// Index on GeoJSON objects>db.articles.ensureIndex( { location: “2dsphere” } )

24

Geo Capabilities

{loc: {type: "Point”, coordinates: [ 40, 5 ] } }

{loc: {type: "LineString",coordinates: [[40, 5], [41, 6]]}}

{loc : {type : "Polygon”, coordinates : [[[0,0],[3,6],[6,1],[0,0]], [[2,2],[3,3],[4,2],[2,2]]]}}

25

• $geoWithin, $geoIntersects, $near

• db.<collection>.find( { <location field> : { $geoWithin : { $box|$polygon|$center : <coordinates> }}})

• db.<collection>.find( { <location field> : { $geoWithin : { $centerSphere : [ [ <x>, <y> ] , <radius> ] } }})

Opérateurs

26

Extension de notre exemple

• Stockage du lieu d’origine du post

• Geolocalisation récupérée depuis le navigateur

Collection article

>db.articles.insert({'text': 'Article

content…’, 'date' : ISODate(...), 'title' : ’Intro to MongoDB’, 'author' : 'Dan Roberts’, 'tags' : ['mongodb',

'database',

'nosql’],

‘location’ : { ‘type’ : ‘Point’, ‘coordinates’ :

[ -0.128, 51.507 ] }

});

//Javascript function to get geolocation.navigator.geolocation.getCurrentPosition();

//You will need to translate into GeoJSON

27

– Requête et explain

Exemple

>db.articles.find( { location :{ $near :

{ $geometry :{ type : "Point" ,coordinates : [-0.128, 51.507] } },

$maxDistance : 5000 }

} )//explain output…{

"cursor" : "S2NearCursor","isMultiKey" : true,"n" : 1,"nscannedObjects" : 1,"nscanned" : 1,….

Text Search

29

• Permet la recherche de texte avec support de :

• Stemming, languages, weighting, phrases et aggregation framework

• Officiel en 2.6

Index text

30

Recherche texte

• Un seul index texte par collection

• Operateur $** pour indexer tous les champs d’une collection

• Utiliser les poids pour modifier l’importance des champs

>db.articles.ensureIndex({text :”text”}

)

>db.articles.ensureIndex( { "$**" : “text”,

name : “TextIndex”} )

>db.articles.ensureIndex( { "$**" : "text”}, { weights :

{ ”title" : 10, ”text" : 5}, name : "TextIndex” })

Operators$text, $search, $language, $meta

31

• Utilisation de $text et $search pour requêter

• Retourne un curseur

• $meta pour la récupération du score

– .// Search articles collection> db.articles.find ({$text: { $search: ”MongoDB" }})

> db.articles.find({ $text: { $search: "MongoDB" }}, { score: { $meta: "textScore" }, _id:0, title:1 } )

{ "title" : "Intro to MongoDB", "score" : 0.75 }

Recherche texte

Résumé

33

• Indexing– #1 pour l’amélioration de la performance….

• Durant le développement, n’oubliez pas– Explain plan– Database profiler

• Geospatial

• Text Search

Summary

34

– Reporting et Analytique– Framework d’agrégation

Prochaine session – 22 Avril

Recommended