4. Les index

  • Auteurs/trices : Adrien VIGUE, Etienne BARON, Camille MONOT

Ce chapitre traite de :

  • Index + requêtes textuelles + requêtes géographiques

4.1. À quoi servent-ils ?

Les index prennent en charge l’exécution efficace des requêtes dans MongoDB. Sans index, MongoDB doit effectuer une analyse de collection , c’est-à-dire analyser chaque document d’une collection, pour sélectionner les documents qui correspondent à l’instruction de requête. Si un index approprié existe pour une requête, MongoDB peut utiliser l’index pour limiter le nombre de documents qu’il doit inspecter. Les index de MongoDB sont similaires aux index d’autres systèmes de base de données. MongoDB définit les index au niveau de la collection et prend en charge les index sur n’importe quel champ ou sous-champ des documents dans une collection MongoDB.

En bref, les index sont un moyen de trouver rapidement et efficacement du contenu dans une base de données.

4.2. Quand les utiliser ?

On met en place des index à chaque fois qu’on s’attend à avoir beaucoup de requêtes sur une clé (resp. un ensemble de clés). Par exemple, on souhaite récupérer les notes d’un étudiant à l’aide de son numéro étudiant. Il faudra alors mettre un index sur la clé “numéro étudiant” afin de réaliser des requêtes efficaces pour retrouver toutes les informations de l’étudiant en fonction de son numéro.

⚠️ Attention

On ne peut pas toujours utiliser des index. En effet, les index rendent la mise à jour de la base fastidieuse : à chaque fois que vous rajoutez de nouvelles données, vous devez redéfinir vos index. Il est donc nécessaire d’utiliser avec parcimonie des index sur une base où vous vous attendez à devoir faire des mises à jour régulières.

4.3. Syntaxe adaptée

  • Création d’un index

db.nomDeLaCollection.createIndex({"cle":1})

On crée ici un index dans la collection ‘collec’ de la base de données courante ‘db’. On donne ensuite le nom du champs sur lequel on va ensuite créer la clé. Le “:1” signifie que l’index va trier les données dans l’ordre croissant.

Exemple :

use food
switched to db food
db.NYfood.createIndex({"borough" : 1})
{
	"numIndexesBefore" : 3,
	"numIndexesAfter" : 4,
	"createdCollectionAutomatically" : false,
	"ok" : 1
}

Ici on crée un index “quartier” dans la collection NYfood de la base food. Le quartier étant une information importante du restaurant, il est judicieux de créer un index pour toutes les requêtes ultérieures.

✍ À noter

Si on avait mis une valeur négative à la place du 1, les données auraient été triées dans l’ordre décroissant. Le tri n’a cependant pas d’importance sur l’efficacité de la requête.

  • Récupération d’index

Lorsque l’on prend en main une nouvelle base mongoDB, il est judicieux de se renseigner sur les index déjà créés, afin de construire les requêtes les plus optimisées possible. Pour cela, on utilise getIndexes :

db.collec.getIndexes()

La syntaxe est très simple et limpide, et donc si l’on applique cette dernière à notre exemple :

db.NYfood.getIndexes()
[
	{
		"v" : 2,
		"key" : {
			"_id" : 1
		},
		"name" : "_id_"
	},
	{
		"v" : 2,
		"key" : {
			"address.loc" : "2dsphere"
		},
		"name" : "address.loc_2dsphere",
		"2dsphereIndexVersion" : 3
	},
	{
		"v" : 2,
		"key" : {
			"_fts" : "text",
			"_ftsx" : 1
		},
		"name" : "$**_text",
		"weights" : {
			"$**" : 1
		},
		"default_language" : "english",
		"language_override" : "language",
		"textIndexVersion" : 3
	},
	{
		"v" : 2,
		"key" : {
			"borough" : 1
		},
		"name" : "borough_1"
	}
]
  • Opérateurs bénéficiant de l’index

Construire une requête mongoDB utilisant des index ne diffèrent pas d’une requête n’en utilisant pas, toutefois, certains opérateurs logiques bénéficient tout particulièrement de la présence d’un ou plusieurs index. Il est donc pertinent de construire des index si vous pensez utiliser ces opérateurs.

Exemple 1 : Opérateur égal (:, $eq)

db.NYfood.find({"cuisine": "Chinese", "borough": "Brooklyn"})
{
	"_id" : ObjectId("62309ad619b1d4e452b4efd8"),
	"address" : {
		"building" : "1269",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-73.871194,
				40.6730975
			]
		},
		"street" : "Sutter Avenue",
		"zipcode" : "11208"
	},
	"borough" : "Brooklyn",
	"cuisine" : "Chinese",
	"grades" : [
		{
			"date" : ISODate("2014-09-16T00:00:00Z"),
			"grade" : "B",
			"score" : 21
		},
		{
			"date" : ISODate("2013-08-28T00:00:00Z"),
			"grade" : "A",
			"score" : 7
		},
		{
			"date" : ISODate("2013-04-02T00:00:00Z"),
			"grade" : "C",
			"score" : 56
		},
		{
			"date" : ISODate("2012-08-15T00:00:00Z"),
			"grade" : "B",
			"score" : 27
		},
		{
			"date" : ISODate("2012-03-28T00:00:00Z"),
			"grade" : "B",
			"score" : 27
		}
	],
	"name" : "May May Kitchen",
	"restaurant_id" : "40358429"
}
{
	"_id" : ObjectId("62309ad619b1d4e452b4effa"),
	"address" : {
		"building" : "976",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-73.92701509999999,
				40.6620192
			]
		},
		"street" : "Rutland Road",
		"zipcode" : "11212"
	},
	"borough" : "Brooklyn",
	"cuisine" : "Chinese",
	"grades" : [
		{
			"date" : ISODate("2014-04-23T00:00:00Z"),
			"grade" : "A",
			"score" : 13
		},
		{
			"date" : ISODate("2013-03-26T00:00:00Z"),
			"grade" : "A",
			"score" : 10
		},
		{
			"date" : ISODate("2012-03-13T00:00:00Z"),
			"grade" : "A",
			"score" : 4
		},
		{
			"date" : ISODate("2011-11-16T00:00:00Z"),
			"grade" : "A",
			"score" : 13
		}
	],
	"name" : "Golden Pavillion",
	"restaurant_id" : "40363920"
}
{
	"_id" : ObjectId("62309ad619b1d4e452b4f27f"),
	"address" : {
		"building" : "152",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-73.986446,
				40.6915505
			]
		},
		"street" : "Lawrence Street",
		"zipcode" : "11201"
	},
	"borough" : "Brooklyn",
	"cuisine" : "Chinese",
	"grades" : [
		{
			"date" : ISODate("2014-10-27T00:00:00Z"),
			"grade" : "A",
			"score" : 5
		},
		{
			"date" : ISODate("2014-04-22T00:00:00Z"),
			"grade" : "A",
			"score" : 12
		},
		{
			"date" : ISODate("2013-08-22T00:00:00Z"),
			"grade" : "C",
			"score" : 52
		},
		{
			"date" : ISODate("2012-12-27T00:00:00Z"),
			"grade" : "A",
			"score" : 12
		},
		{
			"date" : ISODate("2011-12-23T00:00:00Z"),
			"grade" : "A",
			"score" : 9
		}
	],
	"name" : "Lee'S Villa Chinese Restaurant",
	"restaurant_id" : "40388386"
}
{
	"_id" : ObjectId("62309ad619b1d4e452b4f2c5"),
	"address" : {
		"building" : "463",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-73.9667463,
				40.6935651
			]
		},
		"street" : "Myrtle Avenue",
		"zipcode" : "11205"
	},
	"borough" : "Brooklyn",
	"cuisine" : "Chinese",
	"grades" : [
		{
			"date" : ISODate("2014-10-02T00:00:00Z"),
			"grade" : "A",
			"score" : 2
		},
		{
			"date" : ISODate("2013-10-08T00:00:00Z"),
			"grade" : "A",
			"score" : 12
		},
		{
			"date" : ISODate("2012-09-24T00:00:00Z"),
			"grade" : "A",
			"score" : 12
		}
	],
	"name" : "Kum Kau Kitchen",
	"restaurant_id" : "40390653"
}
{
	"_id" : ObjectId("62309ad619b1d4e452b4f2ec"),
	"address" : {
		"building" : "152",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-73.9771312,
				40.67257840000001
			]
		},
		"street" : "7 Avenue",
		"zipcode" : "11215"
	},
	"borough" : "Brooklyn",
	"cuisine" : "Chinese",
	"grades" : [
		{
			"date" : ISODate("2014-10-01T00:00:00Z"),
			"grade" : "A",
			"score" : 9
		},
		{
			"date" : ISODate("2014-03-11T00:00:00Z"),
			"grade" : "A",
			"score" : 12
		},
		{
			"date" : ISODate("2013-02-06T00:00:00Z"),
			"grade" : "A",
			"score" : 12
		},
		{
			"date" : ISODate("2012-01-26T00:00:00Z"),
			"grade" : "A",
			"score" : 13
		}
	],
	"name" : "Szechuan Delight Restaurant",
	"restaurant_id" : "40391528"
}
{
	"_id" : ObjectId("62309ad619b1d4e452b4f324"),
	"address" : {
		"building" : "404",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-73.97635439999999,
				40.6438997
			]
		},
		"street" : "Church Avenue",
		"zipcode" : "11218"
	},
	"borough" : "Brooklyn",
	"cuisine" : "Chinese",
	"grades" : [
		{
			"date" : ISODate("2014-10-29T00:00:00Z"),
			"grade" : "A",
			"score" : 13
		},
		{
			"date" : ISODate("2014-03-24T00:00:00Z"),
			"grade" : "A",
			"score" : 11
		},
		{
			"date" : ISODate("2013-10-25T00:00:00Z"),
			"grade" : "C",
			"score" : 3
		},
		{
			"date" : ISODate("2012-10-01T00:00:00Z"),
			"grade" : "A",
			"score" : 9
		},
		{
			"date" : ISODate("2012-05-09T00:00:00Z"),
			"grade" : "C",
			"score" : 2
		}
	],
	"name" : "Yen Yen Restaurant",
	"restaurant_id" : "40393181"
}
{
	"_id" : ObjectId("62309ad619b1d4e452b4f421"),
	"address" : {
		"building" : "5100",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				80.361767,
				26.4669033
			]
		},
		"street" : "Kings Plaza Shopping Ct",
		"zipcode" : "11234"
	},
	"borough" : "Brooklyn",
	"cuisine" : "Chinese",
	"grades" : [
		{
			"date" : ISODate("2014-04-09T00:00:00Z"),
			"grade" : "A",
			"score" : 9
		},
		{
			"date" : ISODate("2013-04-04T00:00:00Z"),
			"grade" : "A",
			"score" : 13
		},
		{
			"date" : ISODate("2012-10-10T00:00:00Z"),
			"grade" : "B",
			"score" : 17
		},
		{
			"date" : ISODate("2012-05-10T00:00:00Z"),
			"grade" : "A",
			"score" : 13
		},
		{
			"date" : ISODate("2011-10-20T00:00:00Z"),
			"grade" : "B",
			"score" : 22
		}
	],
	"name" : "Master Wok",
	"restaurant_id" : "40398688"
}
{
	"_id" : ObjectId("62309ad619b1d4e452b4f42b"),
	"address" : {
		"building" : "425",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-73.96837599999999,
				40.59775399999999
			]
		},
		"street" : "Avenue U",
		"zipcode" : "11223"
	},
	"borough" : "Brooklyn",
	"cuisine" : "Chinese",
	"grades" : [
		{
			"date" : ISODate("2014-10-09T00:00:00Z"),
			"grade" : "A",
			"score" : 12
		},
		{
			"date" : ISODate("2013-10-10T00:00:00Z"),
			"grade" : "A",
			"score" : 9
		},
		{
			"date" : ISODate("2012-10-01T00:00:00Z"),
			"grade" : "A",
			"score" : 8
		},
		{
			"date" : ISODate("2011-10-25T00:00:00Z"),
			"grade" : "A",
			"score" : 11
		}
	],
	"name" : "Choy Le Chinese Restaurant",
	"restaurant_id" : "40398904"
}
{
	"_id" : ObjectId("62309ad619b1d4e452b4f63f"),
	"address" : {
		"building" : "1955",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-73.9988983,
				40.6052988
			]
		},
		"street" : "86 Street",
		"zipcode" : "11214"
	},
	"borough" : "Brooklyn",
	"cuisine" : "Chinese",
	"grades" : [
		{
			"date" : ISODate("2014-10-31T00:00:00Z"),
			"grade" : "B",
			"score" : 17
		},
		{
			"date" : ISODate("2013-09-17T00:00:00Z"),
			"grade" : "A",
			"score" : 10
		},
		{
			"date" : ISODate("2013-04-30T00:00:00Z"),
			"grade" : "A",
			"score" : 12
		},
		{
			"date" : ISODate("2012-09-05T00:00:00Z"),
			"grade" : "B",
			"score" : 27
		},
		{
			"date" : ISODate("2012-02-07T00:00:00Z"),
			"grade" : "B",
			"score" : 20
		}
	],
	"name" : "New Ruan'S Restaurant",
	"restaurant_id" : "40537963"
}
{
	"_id" : ObjectId("62309ad619b1d4e452b4f762"),
	"address" : {
		"building" : "6820",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-74.0122391,
				40.6289332
			]
		},
		"street" : "Fort Hamilton Parkway",
		"zipcode" : "11219"
	},
	"borough" : "Brooklyn",
	"cuisine" : "Chinese",
	"grades" : [
		{
			"date" : ISODate("2014-11-19T00:00:00Z"),
			"grade" : "A",
			"score" : 4
		},
		{
			"date" : ISODate("2013-12-09T00:00:00Z"),
			"grade" : "A",
			"score" : 9
		},
		{
			"date" : ISODate("2012-12-05T00:00:00Z"),
			"grade" : "A",
			"score" : 11
		},
		{
			"date" : ISODate("2012-05-22T00:00:00Z"),
			"grade" : "A",
			"score" : 10
		}
	],
	"name" : "Great Wall Restaurant",
	"restaurant_id" : "40574067"
}
Type "it" for more

On récupère les restaurants proposant de la cuisine chinoise dans le quartier de Brooklyn.

Exemple 2 : Opérateur infériorité/supériorité ($lt, $lte, $gt, $gte)

db.NYfood.find({"name": {$gte: "C", $lt: "D"}})
{
	"_id" : ObjectId("62309ad619b1d4e452b4efd6"),
	"address" : {
		"building" : "7715",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-73.9973325,
				40.61174889999999
			]
		},
		"street" : "18 Avenue",
		"zipcode" : "11214"
	},
	"borough" : "Brooklyn",
	"cuisine" : "American ",
	"grades" : [
		{
			"date" : ISODate("2014-04-16T00:00:00Z"),
			"grade" : "A",
			"score" : 5
		},
		{
			"date" : ISODate("2013-04-23T00:00:00Z"),
			"grade" : "A",
			"score" : 2
		},
		{
			"date" : ISODate("2012-04-24T00:00:00Z"),
			"grade" : "A",
			"score" : 5
		},
		{
			"date" : ISODate("2011-12-16T00:00:00Z"),
			"grade" : "A",
			"score" : 2
		}
	],
	"name" : "C & C Catering Service",
	"restaurant_id" : "40357437"
}
{
	"_id" : ObjectId("62309ad619b1d4e452b4efdb"),
	"address" : {
		"building" : "265-15",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-73.7032601,
				40.7386417
			]
		},
		"street" : "Hillside Avenue",
		"zipcode" : "11004"
	},
	"borough" : "Queens",
	"cuisine" : "Ice Cream, Gelato, Yogurt, Ices",
	"grades" : [
		{
			"date" : ISODate("2014-10-28T00:00:00Z"),
			"grade" : "A",
			"score" : 9
		},
		{
			"date" : ISODate("2013-09-18T00:00:00Z"),
			"grade" : "A",
			"score" : 10
		},
		{
			"date" : ISODate("2012-09-20T00:00:00Z"),
			"grade" : "A",
			"score" : 13
		}
	],
	"name" : "Carvel Ice Cream",
	"restaurant_id" : "40361322"
}
{
	"_id" : ObjectId("62309ad619b1d4e452b4efdc"),
	"address" : {
		"building" : "203",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-73.97822040000001,
				40.6435254
			]
		},
		"street" : "Church Avenue",
		"zipcode" : "11218"
	},
	"borough" : "Brooklyn",
	"cuisine" : "Ice Cream, Gelato, Yogurt, Ices",
	"grades" : [
		{
			"date" : ISODate("2014-02-10T00:00:00Z"),
			"grade" : "A",
			"score" : 2
		},
		{
			"date" : ISODate("2013-01-02T00:00:00Z"),
			"grade" : "A",
			"score" : 13
		},
		{
			"date" : ISODate("2012-01-09T00:00:00Z"),
			"grade" : "A",
			"score" : 3
		},
		{
			"date" : ISODate("2011-11-07T00:00:00Z"),
			"grade" : "P",
			"score" : 12
		},
		{
			"date" : ISODate("2011-07-21T00:00:00Z"),
			"grade" : "A",
			"score" : 13
		}
	],
	"name" : "Carvel Ice Cream",
	"restaurant_id" : "40360076"
}
{
	"_id" : ObjectId("62309ad619b1d4e452b4efec"),
	"address" : {
		"building" : "1006",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-73.84856870000002,
				40.8903781
			]
		},
		"street" : "East 233 Street",
		"zipcode" : "10466"
	},
	"borough" : "Bronx",
	"cuisine" : "Ice Cream, Gelato, Yogurt, Ices",
	"grades" : [
		{
			"date" : ISODate("2014-04-24T00:00:00Z"),
			"grade" : "A",
			"score" : 10
		},
		{
			"date" : ISODate("2013-09-05T00:00:00Z"),
			"grade" : "A",
			"score" : 10
		},
		{
			"date" : ISODate("2013-02-21T00:00:00Z"),
			"grade" : "A",
			"score" : 9
		},
		{
			"date" : ISODate("2012-07-03T00:00:00Z"),
			"grade" : "A",
			"score" : 11
		},
		{
			"date" : ISODate("2011-07-11T00:00:00Z"),
			"grade" : "A",
			"score" : 5
		}
	],
	"name" : "Carvel Ice Cream",
	"restaurant_id" : "40363093"
}
{
	"_id" : ObjectId("62309ad619b1d4e452b4eff0"),
	"address" : {
		"building" : "625",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-73.990494,
				40.7569545
			]
		},
		"street" : "8 Avenue",
		"zipcode" : "10018"
	},
	"borough" : "Manhattan",
	"cuisine" : "American ",
	"grades" : [
		{
			"date" : ISODate("2014-06-09T00:00:00Z"),
			"grade" : "A",
			"score" : 12
		},
		{
			"date" : ISODate("2014-01-10T00:00:00Z"),
			"grade" : "A",
			"score" : 9
		},
		{
			"date" : ISODate("2012-12-07T00:00:00Z"),
			"grade" : "A",
			"score" : 4
		},
		{
			"date" : ISODate("2011-12-13T00:00:00Z"),
			"grade" : "A",
			"score" : 9
		},
		{
			"date" : ISODate("2011-09-09T00:00:00Z"),
			"grade" : "A",
			"score" : 13
		}
	],
	"name" : "Cafe Metro",
	"restaurant_id" : "40363298"
}
{
	"_id" : ObjectId("62309ad619b1d4e452b4effb"),
	"address" : {
		"building" : "1111",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-74.0796436,
				40.59878339999999
			]
		},
		"street" : "Hylan Boulevard",
		"zipcode" : "10305"
	},
	"borough" : "Staten Island",
	"cuisine" : "Ice Cream, Gelato, Yogurt, Ices",
	"grades" : [
		{
			"date" : ISODate("2014-04-24T00:00:00Z"),
			"grade" : "A",
			"score" : 12
		},
		{
			"date" : ISODate("2013-02-26T00:00:00Z"),
			"grade" : "A",
			"score" : 5
		},
		{
			"date" : ISODate("2012-02-02T00:00:00Z"),
			"grade" : "A",
			"score" : 2
		}
	],
	"name" : "Carvel Ice Cream",
	"restaurant_id" : "40363834"
}
{
	"_id" : ObjectId("62309ad619b1d4e452b4f00d"),
	"address" : {
		"building" : "100",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-74.0010484,
				40.71599000000001
			]
		},
		"street" : "Centre Street",
		"zipcode" : "10013"
	},
	"borough" : "Manhattan",
	"cuisine" : "American ",
	"grades" : [
		{
			"date" : ISODate("2014-03-03T00:00:00Z"),
			"grade" : "A",
			"score" : 8
		},
		{
			"date" : ISODate("2013-03-08T00:00:00Z"),
			"grade" : "A",
			"score" : 12
		},
		{
			"date" : ISODate("2012-03-09T00:00:00Z"),
			"grade" : "A",
			"score" : 13
		},
		{
			"date" : ISODate("2011-03-31T00:00:00Z"),
			"grade" : "A",
			"score" : 12
		}
	],
	"name" : "Criminal Court Bldg Cafeteria",
	"restaurant_id" : "40364443"
}
{
	"_id" : ObjectId("62309ad619b1d4e452b4f013"),
	"address" : {
		"building" : "215",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-73.9805679,
				40.7659436
			]
		},
		"street" : "West 57 Street",
		"zipcode" : "10019"
	},
	"borough" : "Manhattan",
	"cuisine" : "American ",
	"grades" : [
		{
			"date" : ISODate("2014-09-25T00:00:00Z"),
			"grade" : "A",
			"score" : 12
		},
		{
			"date" : ISODate("2014-02-14T00:00:00Z"),
			"grade" : "A",
			"score" : 12
		},
		{
			"date" : ISODate("2013-08-09T00:00:00Z"),
			"grade" : "A",
			"score" : 2
		},
		{
			"date" : ISODate("2013-02-22T00:00:00Z"),
			"grade" : "B",
			"score" : 20
		},
		{
			"date" : ISODate("2012-02-16T00:00:00Z"),
			"grade" : "A",
			"score" : 8
		}
	],
	"name" : "Cafe Atelier (Art Students League)",
	"restaurant_id" : "40364531"
}
{
	"_id" : ObjectId("62309ad619b1d4e452b4f023"),
	"address" : {
		"building" : "67",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-74.0707363,
				40.59321569999999
			]
		},
		"street" : "Olympia Boulevard",
		"zipcode" : "10305"
	},
	"borough" : "Staten Island",
	"cuisine" : "Italian",
	"grades" : [
		{
			"date" : ISODate("2014-04-24T00:00:00Z"),
			"grade" : "A",
			"score" : 13
		},
		{
			"date" : ISODate("2013-04-04T00:00:00Z"),
			"grade" : "A",
			"score" : 2
		},
		{
			"date" : ISODate("2012-02-02T00:00:00Z"),
			"grade" : "A",
			"score" : 5
		},
		{
			"date" : ISODate("2011-07-23T00:00:00Z"),
			"grade" : "A",
			"score" : 11
		}
	],
	"name" : "Crystal Room",
	"restaurant_id" : "40365013"
}
{
	"_id" : ObjectId("62309ad619b1d4e452b4f029"),
	"address" : {
		"building" : "331",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-74.0037823,
				40.7380122
			]
		},
		"street" : "West    4 Street",
		"zipcode" : "10014"
	},
	"borough" : "Manhattan",
	"cuisine" : "American ",
	"grades" : [
		{
			"date" : ISODate("2014-11-17T00:00:00Z"),
			"grade" : "A",
			"score" : 12
		},
		{
			"date" : ISODate("2014-06-27T00:00:00Z"),
			"grade" : "A",
			"score" : 5
		},
		{
			"date" : ISODate("2013-05-15T00:00:00Z"),
			"grade" : "A",
			"score" : 4
		},
		{
			"date" : ISODate("2012-05-09T00:00:00Z"),
			"grade" : "A",
			"score" : 12
		}
	],
	"name" : "Corner Bistro",
	"restaurant_id" : "40365166"
}
Type "it" for more

On récupère les restaurant dont le nom est situé entre “C” et “D” dans l’ordre lexicographique.

Exemple 3 : différence d’exécution avec et sans index

Reprenons la requête vue à l’exemple 1, mais cette fois affichons son temps d’exécution :

db.NYfood.find({"cuisine": "Chinese", "borough": "Brooklyn"}).explain("executionStats")
{
	"explainVersion" : "1",
	"queryPlanner" : {
		"namespace" : "food.NYfood",
		"indexFilterSet" : false,
		"parsedQuery" : {
			"$and" : [
				{
					"borough" : {
						"$eq" : "Brooklyn"
					}
				},
				{
					"cuisine" : {
						"$eq" : "Chinese"
					}
				}
			]
		},
		"maxIndexedOrSolutionsReached" : false,
		"maxIndexedAndSolutionsReached" : false,
		"maxScansToExplodeReached" : false,
		"winningPlan" : {
			"stage" : "FETCH",
			"filter" : {
				"cuisine" : {
					"$eq" : "Chinese"
				}
			},
			"inputStage" : {
				"stage" : "IXSCAN",
				"keyPattern" : {
					"borough" : 1
				},
				"indexName" : "borough_1",
				"isMultiKey" : false,
				"multiKeyPaths" : {
					"borough" : [ ]
				},
				"isUnique" : false,
				"isSparse" : false,
				"isPartial" : false,
				"indexVersion" : 2,
				"direction" : "forward",
				"indexBounds" : {
					"borough" : [
						"[\"Brooklyn\", \"Brooklyn\"]"
					]
				}
			}
		},
		"rejectedPlans" : [ ]
	},
	"executionStats" : {
		"executionSuccess" : true,
		"nReturned" : 763,
		"executionTimeMillis" : 9,
		"totalKeysExamined" : 6085,
		"totalDocsExamined" : 6085,
		"executionStages" : {
			"stage" : "FETCH",
			"filter" : {
				"cuisine" : {
					"$eq" : "Chinese"
				}
			},
			"nReturned" : 763,
			"executionTimeMillisEstimate" : 0,
			"works" : 6086,
			"advanced" : 763,
			"needTime" : 5322,
			"needYield" : 0,
			"saveState" : 6,
			"restoreState" : 6,
			"isEOF" : 1,
			"docsExamined" : 6085,
			"alreadyHasObj" : 0,
			"inputStage" : {
				"stage" : "IXSCAN",
				"nReturned" : 6085,
				"executionTimeMillisEstimate" : 0,
				"works" : 6086,
				"advanced" : 6085,
				"needTime" : 0,
				"needYield" : 0,
				"saveState" : 6,
				"restoreState" : 6,
				"isEOF" : 1,
				"keyPattern" : {
					"borough" : 1
				},
				"indexName" : "borough_1",
				"isMultiKey" : false,
				"multiKeyPaths" : {
					"borough" : [ ]
				},
				"isUnique" : false,
				"isSparse" : false,
				"isPartial" : false,
				"indexVersion" : 2,
				"direction" : "forward",
				"indexBounds" : {
					"borough" : [
						"[\"Brooklyn\", \"Brooklyn\"]"
					]
				},
				"keysExamined" : 6085,
				"seeks" : 1,
				"dupsTested" : 0,
				"dupsDropped" : 0
			}
		}
	},
	"command" : {
		"find" : "NYfood",
		"filter" : {
			"cuisine" : "Chinese",
			"borough" : "Brooklyn"
		},
		"$db" : "food"
	},
	"serverInfo" : {
		"host" : "6d4c71b2bc66",
		"port" : 27017,
		"version" : "5.0.6",
		"gitVersion" : "212a8dbb47f07427dae194a9c75baec1d81d9259"
	},
	"serverParameters" : {
		"internalQueryFacetBufferSizeBytes" : 104857600,
		"internalQueryFacetMaxOutputDocSizeBytes" : 104857600,
		"internalLookupStageIntermediateDocumentMaxSizeBytes" : 104857600,
		"internalDocumentSourceGroupMaxMemoryBytes" : 104857600,
		"internalQueryMaxBlockingSortMemoryUsageBytes" : 104857600,
		"internalQueryProhibitBlockingMergeOnMongoS" : 0,
		"internalQueryMaxAddToSetBytes" : 104857600,
		"internalDocumentSourceSetWindowFieldsMaxMemoryBytes" : 104857600
	},
	"ok" : 1
}

Rajoutons maintenant l’index “cuisine” (l’index quartier ayant déjà été créé plus haut) :

db.NYfood.createIndex({"cuisine": 1})
{
	"numIndexesBefore" : 4,
	"numIndexesAfter" : 5,
	"createdCollectionAutomatically" : false,
	"ok" : 1
}

On peut maintenant relancer la requête et observer la différence :

db.NYfood.find({"cuisine": "Chinese", "borough": "Brooklyn"}).explain("executionStats")
{
	"explainVersion" : "1",
	"queryPlanner" : {
		"namespace" : "food.NYfood",
		"indexFilterSet" : false,
		"parsedQuery" : {
			"$and" : [
				{
					"borough" : {
						"$eq" : "Brooklyn"
					}
				},
				{
					"cuisine" : {
						"$eq" : "Chinese"
					}
				}
			]
		},
		"maxIndexedOrSolutionsReached" : false,
		"maxIndexedAndSolutionsReached" : false,
		"maxScansToExplodeReached" : false,
		"winningPlan" : {
			"stage" : "FETCH",
			"filter" : {
				"borough" : {
					"$eq" : "Brooklyn"
				}
			},
			"inputStage" : {
				"stage" : "IXSCAN",
				"keyPattern" : {
					"cuisine" : 1
				},
				"indexName" : "cuisine_1",
				"isMultiKey" : false,
				"multiKeyPaths" : {
					"cuisine" : [ ]
				},
				"isUnique" : false,
				"isSparse" : false,
				"isPartial" : false,
				"indexVersion" : 2,
				"direction" : "forward",
				"indexBounds" : {
					"cuisine" : [
						"[\"Chinese\", \"Chinese\"]"
					]
				}
			}
		},
		"rejectedPlans" : [
			{
				"stage" : "FETCH",
				"filter" : {
					"cuisine" : {
						"$eq" : "Chinese"
					}
				},
				"inputStage" : {
					"stage" : "IXSCAN",
					"keyPattern" : {
						"borough" : 1
					},
					"indexName" : "borough_1",
					"isMultiKey" : false,
					"multiKeyPaths" : {
						"borough" : [ ]
					},
					"isUnique" : false,
					"isSparse" : false,
					"isPartial" : false,
					"indexVersion" : 2,
					"direction" : "forward",
					"indexBounds" : {
						"borough" : [
							"[\"Brooklyn\", \"Brooklyn\"]"
						]
					}
				}
			},
			{
				"stage" : "FETCH",
				"filter" : {
					"$and" : [
						{
							"borough" : {
								"$eq" : "Brooklyn"
							}
						},
						{
							"cuisine" : {
								"$eq" : "Chinese"
							}
						}
					]
				},
				"inputStage" : {
					"stage" : "AND_SORTED",
					"inputStages" : [
						{
							"stage" : "IXSCAN",
							"keyPattern" : {
								"borough" : 1
							},
							"indexName" : "borough_1",
							"isMultiKey" : false,
							"multiKeyPaths" : {
								"borough" : [ ]
							},
							"isUnique" : false,
							"isSparse" : false,
							"isPartial" : false,
							"indexVersion" : 2,
							"direction" : "forward",
							"indexBounds" : {
								"borough" : [
									"[\"Brooklyn\", \"Brooklyn\"]"
								]
							}
						},
						{
							"stage" : "IXSCAN",
							"keyPattern" : {
								"cuisine" : 1
							},
							"indexName" : "cuisine_1",
							"isMultiKey" : false,
							"multiKeyPaths" : {
								"cuisine" : [ ]
							},
							"isUnique" : false,
							"isSparse" : false,
							"isPartial" : false,
							"indexVersion" : 2,
							"direction" : "forward",
							"indexBounds" : {
								"cuisine" : [
									"[\"Chinese\", \"Chinese\"]"
								]
							}
						}
					]
				}
			}
		]
	},
	"executionStats" : {
		"executionSuccess" : true,
		"nReturned" : 763,
		"executionTimeMillis" : 5,
		"totalKeysExamined" : 2418,
		"totalDocsExamined" : 2418,
		"executionStages" : {
			"stage" : "FETCH",
			"filter" : {
				"borough" : {
					"$eq" : "Brooklyn"
				}
			},
			"nReturned" : 763,
			"executionTimeMillisEstimate" : 0,
			"works" : 2419,
			"advanced" : 763,
			"needTime" : 1655,
			"needYield" : 0,
			"saveState" : 3,
			"restoreState" : 3,
			"isEOF" : 1,
			"docsExamined" : 2418,
			"alreadyHasObj" : 0,
			"inputStage" : {
				"stage" : "IXSCAN",
				"nReturned" : 2418,
				"executionTimeMillisEstimate" : 0,
				"works" : 2419,
				"advanced" : 2418,
				"needTime" : 0,
				"needYield" : 0,
				"saveState" : 3,
				"restoreState" : 3,
				"isEOF" : 1,
				"keyPattern" : {
					"cuisine" : 1
				},
				"indexName" : "cuisine_1",
				"isMultiKey" : false,
				"multiKeyPaths" : {
					"cuisine" : [ ]
				},
				"isUnique" : false,
				"isSparse" : false,
				"isPartial" : false,
				"indexVersion" : 2,
				"direction" : "forward",
				"indexBounds" : {
					"cuisine" : [
						"[\"Chinese\", \"Chinese\"]"
					]
				},
				"keysExamined" : 2418,
				"seeks" : 1,
				"dupsTested" : 0,
				"dupsDropped" : 0
			}
		}
	},
	"command" : {
		"find" : "NYfood",
		"filter" : {
			"cuisine" : "Chinese",
			"borough" : "Brooklyn"
		},
		"$db" : "food"
	},
	"serverInfo" : {
		"host" : "6d4c71b2bc66",
		"port" : 27017,
		"version" : "5.0.6",
		"gitVersion" : "212a8dbb47f07427dae194a9c75baec1d81d9259"
	},
	"serverParameters" : {
		"internalQueryFacetBufferSizeBytes" : 104857600,
		"internalQueryFacetMaxOutputDocSizeBytes" : 104857600,
		"internalLookupStageIntermediateDocumentMaxSizeBytes" : 104857600,
		"internalDocumentSourceGroupMaxMemoryBytes" : 104857600,
		"internalQueryMaxBlockingSortMemoryUsageBytes" : 104857600,
		"internalQueryProhibitBlockingMergeOnMongoS" : 0,
		"internalQueryMaxAddToSetBytes" : 104857600,
		"internalDocumentSourceSetWindowFieldsMaxMemoryBytes" : 104857600
	},
	"ok" : 1
}

4.4. Index composés

Il est également possible de créer des index non pas sur un mais sur plusieurs champs de la base de données, on appelle alors un tel index un “index composé”. L’intérêt d’une telle pratique est de lier des champs entre eux et d’optimiser grandement des requêtes portant sur ces derniers. Si l’on s’attend à effectuer de telles requêtes, alors créer un index composé devient judicieux.

  • Création d’un index composé

db.nomDeLaCollection.createIndex({"cle1": 1, "cle2": 1}

⚠️ Attention

L’ordre dans lequel vous déclarez vos champs à une importance capitale dans le résultat renvoyé par la requête. Par exemple, l’index composé suivant : db.nomDeLaCollection.createIndex({“cle2”: 1, “cle1”: 1}, ne correspond pas du tout à l’index vu juste au-dessus. Certaines requêtes pourront ainsi être accélérées par l’un ou l’autre des index mais pas forcément par les deux.

  • Exemple de requête utilisant un index composé

Nous avons déjà vu un tel exemple, en effet si nous revenons un peu plus haut, nous avons déjà donné une requête de ce type :

db.NYfood.find({"cuisine": "Chinese", "borough": "Brooklyn"}).explain("executionStats")
{
	"explainVersion" : "1",
	"queryPlanner" : {
		"namespace" : "food.NYfood",
		"indexFilterSet" : false,
		"parsedQuery" : {
			"$and" : [
				{
					"borough" : {
						"$eq" : "Brooklyn"
					}
				},
				{
					"cuisine" : {
						"$eq" : "Chinese"
					}
				}
			]
		},
		"maxIndexedOrSolutionsReached" : false,
		"maxIndexedAndSolutionsReached" : false,
		"maxScansToExplodeReached" : false,
		"winningPlan" : {
			"stage" : "FETCH",
			"filter" : {
				"borough" : {
					"$eq" : "Brooklyn"
				}
			},
			"inputStage" : {
				"stage" : "IXSCAN",
				"keyPattern" : {
					"cuisine" : 1
				},
				"indexName" : "cuisine_1",
				"isMultiKey" : false,
				"multiKeyPaths" : {
					"cuisine" : [ ]
				},
				"isUnique" : false,
				"isSparse" : false,
				"isPartial" : false,
				"indexVersion" : 2,
				"direction" : "forward",
				"indexBounds" : {
					"cuisine" : [
						"[\"Chinese\", \"Chinese\"]"
					]
				}
			}
		},
		"rejectedPlans" : [
			{
				"stage" : "FETCH",
				"filter" : {
					"cuisine" : {
						"$eq" : "Chinese"
					}
				},
				"inputStage" : {
					"stage" : "IXSCAN",
					"keyPattern" : {
						"borough" : 1
					},
					"indexName" : "borough_1",
					"isMultiKey" : false,
					"multiKeyPaths" : {
						"borough" : [ ]
					},
					"isUnique" : false,
					"isSparse" : false,
					"isPartial" : false,
					"indexVersion" : 2,
					"direction" : "forward",
					"indexBounds" : {
						"borough" : [
							"[\"Brooklyn\", \"Brooklyn\"]"
						]
					}
				}
			},
			{
				"stage" : "FETCH",
				"filter" : {
					"$and" : [
						{
							"borough" : {
								"$eq" : "Brooklyn"
							}
						},
						{
							"cuisine" : {
								"$eq" : "Chinese"
							}
						}
					]
				},
				"inputStage" : {
					"stage" : "AND_SORTED",
					"inputStages" : [
						{
							"stage" : "IXSCAN",
							"keyPattern" : {
								"borough" : 1
							},
							"indexName" : "borough_1",
							"isMultiKey" : false,
							"multiKeyPaths" : {
								"borough" : [ ]
							},
							"isUnique" : false,
							"isSparse" : false,
							"isPartial" : false,
							"indexVersion" : 2,
							"direction" : "forward",
							"indexBounds" : {
								"borough" : [
									"[\"Brooklyn\", \"Brooklyn\"]"
								]
							}
						},
						{
							"stage" : "IXSCAN",
							"keyPattern" : {
								"cuisine" : 1
							},
							"indexName" : "cuisine_1",
							"isMultiKey" : false,
							"multiKeyPaths" : {
								"cuisine" : [ ]
							},
							"isUnique" : false,
							"isSparse" : false,
							"isPartial" : false,
							"indexVersion" : 2,
							"direction" : "forward",
							"indexBounds" : {
								"cuisine" : [
									"[\"Chinese\", \"Chinese\"]"
								]
							}
						}
					]
				}
			}
		]
	},
	"executionStats" : {
		"executionSuccess" : true,
		"nReturned" : 763,
		"executionTimeMillis" : 5,
		"totalKeysExamined" : 2418,
		"totalDocsExamined" : 2418,
		"executionStages" : {
			"stage" : "FETCH",
			"filter" : {
				"borough" : {
					"$eq" : "Brooklyn"
				}
			},
			"nReturned" : 763,
			"executionTimeMillisEstimate" : 0,
			"works" : 2419,
			"advanced" : 763,
			"needTime" : 1655,
			"needYield" : 0,
			"saveState" : 3,
			"restoreState" : 3,
			"isEOF" : 1,
			"docsExamined" : 2418,
			"alreadyHasObj" : 0,
			"inputStage" : {
				"stage" : "IXSCAN",
				"nReturned" : 2418,
				"executionTimeMillisEstimate" : 0,
				"works" : 2419,
				"advanced" : 2418,
				"needTime" : 0,
				"needYield" : 0,
				"saveState" : 3,
				"restoreState" : 3,
				"isEOF" : 1,
				"keyPattern" : {
					"cuisine" : 1
				},
				"indexName" : "cuisine_1",
				"isMultiKey" : false,
				"multiKeyPaths" : {
					"cuisine" : [ ]
				},
				"isUnique" : false,
				"isSparse" : false,
				"isPartial" : false,
				"indexVersion" : 2,
				"direction" : "forward",
				"indexBounds" : {
					"cuisine" : [
						"[\"Chinese\", \"Chinese\"]"
					]
				},
				"keysExamined" : 2418,
				"seeks" : 1,
				"dupsTested" : 0,
				"dupsDropped" : 0
			}
		}
	},
	"command" : {
		"find" : "NYfood",
		"filter" : {
			"cuisine" : "Chinese",
			"borough" : "Brooklyn"
		},
		"$db" : "food"
	},
	"serverInfo" : {
		"host" : "6d4c71b2bc66",
		"port" : 27017,
		"version" : "5.0.6",
		"gitVersion" : "212a8dbb47f07427dae194a9c75baec1d81d9259"
	},
	"serverParameters" : {
		"internalQueryFacetBufferSizeBytes" : 104857600,
		"internalQueryFacetMaxOutputDocSizeBytes" : 104857600,
		"internalLookupStageIntermediateDocumentMaxSizeBytes" : 104857600,
		"internalDocumentSourceGroupMaxMemoryBytes" : 104857600,
		"internalQueryMaxBlockingSortMemoryUsageBytes" : 104857600,
		"internalQueryProhibitBlockingMergeOnMongoS" : 0,
		"internalQueryMaxAddToSetBytes" : 104857600,
		"internalDocumentSourceSetWindowFieldsMaxMemoryBytes" : 104857600
	},
	"ok" : 1
}

Ici, on pourrait profiter d’un index composé sur les attributs “cuisine” et “borough” :

db.NYfood.createIndex({"cuisine": 1, "borough": 1})
{
	"numIndexesBefore" : 5,
	"numIndexesAfter" : 6,
	"createdCollectionAutomatically" : false,
	"ok" : 1
}

Répétons notre requête pour voir l’intérêt de notre nouvel index :

db.NYfood.find({"cuisine": "Chinese", "borough": "Brooklyn"}).explain("executionStats")
{
	"explainVersion" : "1",
	"queryPlanner" : {
		"namespace" : "food.NYfood",
		"indexFilterSet" : false,
		"parsedQuery" : {
			"$and" : [
				{
					"borough" : {
						"$eq" : "Brooklyn"
					}
				},
				{
					"cuisine" : {
						"$eq" : "Chinese"
					}
				}
			]
		},
		"maxIndexedOrSolutionsReached" : false,
		"maxIndexedAndSolutionsReached" : false,
		"maxScansToExplodeReached" : false,
		"winningPlan" : {
			"stage" : "FETCH",
			"inputStage" : {
				"stage" : "IXSCAN",
				"keyPattern" : {
					"cuisine" : 1,
					"borough" : 1
				},
				"indexName" : "cuisine_1_borough_1",
				"isMultiKey" : false,
				"multiKeyPaths" : {
					"cuisine" : [ ],
					"borough" : [ ]
				},
				"isUnique" : false,
				"isSparse" : false,
				"isPartial" : false,
				"indexVersion" : 2,
				"direction" : "forward",
				"indexBounds" : {
					"cuisine" : [
						"[\"Chinese\", \"Chinese\"]"
					],
					"borough" : [
						"[\"Brooklyn\", \"Brooklyn\"]"
					]
				}
			}
		},
		"rejectedPlans" : [
			{
				"stage" : "FETCH",
				"filter" : {
					"cuisine" : {
						"$eq" : "Chinese"
					}
				},
				"inputStage" : {
					"stage" : "IXSCAN",
					"keyPattern" : {
						"borough" : 1
					},
					"indexName" : "borough_1",
					"isMultiKey" : false,
					"multiKeyPaths" : {
						"borough" : [ ]
					},
					"isUnique" : false,
					"isSparse" : false,
					"isPartial" : false,
					"indexVersion" : 2,
					"direction" : "forward",
					"indexBounds" : {
						"borough" : [
							"[\"Brooklyn\", \"Brooklyn\"]"
						]
					}
				}
			},
			{
				"stage" : "FETCH",
				"filter" : {
					"borough" : {
						"$eq" : "Brooklyn"
					}
				},
				"inputStage" : {
					"stage" : "IXSCAN",
					"keyPattern" : {
						"cuisine" : 1
					},
					"indexName" : "cuisine_1",
					"isMultiKey" : false,
					"multiKeyPaths" : {
						"cuisine" : [ ]
					},
					"isUnique" : false,
					"isSparse" : false,
					"isPartial" : false,
					"indexVersion" : 2,
					"direction" : "forward",
					"indexBounds" : {
						"cuisine" : [
							"[\"Chinese\", \"Chinese\"]"
						]
					}
				}
			}
		]
	},
	"executionStats" : {
		"executionSuccess" : true,
		"nReturned" : 763,
		"executionTimeMillis" : 2,
		"totalKeysExamined" : 763,
		"totalDocsExamined" : 763,
		"executionStages" : {
			"stage" : "FETCH",
			"nReturned" : 763,
			"executionTimeMillisEstimate" : 0,
			"works" : 764,
			"advanced" : 763,
			"needTime" : 0,
			"needYield" : 0,
			"saveState" : 1,
			"restoreState" : 1,
			"isEOF" : 1,
			"docsExamined" : 763,
			"alreadyHasObj" : 0,
			"inputStage" : {
				"stage" : "IXSCAN",
				"nReturned" : 763,
				"executionTimeMillisEstimate" : 0,
				"works" : 764,
				"advanced" : 763,
				"needTime" : 0,
				"needYield" : 0,
				"saveState" : 1,
				"restoreState" : 1,
				"isEOF" : 1,
				"keyPattern" : {
					"cuisine" : 1,
					"borough" : 1
				},
				"indexName" : "cuisine_1_borough_1",
				"isMultiKey" : false,
				"multiKeyPaths" : {
					"cuisine" : [ ],
					"borough" : [ ]
				},
				"isUnique" : false,
				"isSparse" : false,
				"isPartial" : false,
				"indexVersion" : 2,
				"direction" : "forward",
				"indexBounds" : {
					"cuisine" : [
						"[\"Chinese\", \"Chinese\"]"
					],
					"borough" : [
						"[\"Brooklyn\", \"Brooklyn\"]"
					]
				},
				"keysExamined" : 763,
				"seeks" : 1,
				"dupsTested" : 0,
				"dupsDropped" : 0
			}
		}
	},
	"command" : {
		"find" : "NYfood",
		"filter" : {
			"cuisine" : "Chinese",
			"borough" : "Brooklyn"
		},
		"$db" : "food"
	},
	"serverInfo" : {
		"host" : "6d4c71b2bc66",
		"port" : 27017,
		"version" : "5.0.6",
		"gitVersion" : "212a8dbb47f07427dae194a9c75baec1d81d9259"
	},
	"serverParameters" : {
		"internalQueryFacetBufferSizeBytes" : 104857600,
		"internalQueryFacetMaxOutputDocSizeBytes" : 104857600,
		"internalLookupStageIntermediateDocumentMaxSizeBytes" : 104857600,
		"internalDocumentSourceGroupMaxMemoryBytes" : 104857600,
		"internalQueryMaxBlockingSortMemoryUsageBytes" : 104857600,
		"internalQueryProhibitBlockingMergeOnMongoS" : 0,
		"internalQueryMaxAddToSetBytes" : 104857600,
		"internalDocumentSourceSetWindowFieldsMaxMemoryBytes" : 104857600
	},
	"ok" : 1
}

4.5. Requêtes et Index textuels

Lorsque l’on veut interroger notre base de données sur un champ de type “chaîne de caractères”, deux méthodes s’offrent à nous : on peut utiliser soit des requêtes régulières, soit un index textuel qui a été créé sur-le-champ. L’avantage de la première méthode est une très grande précision, et on l’utilisera donc lorsque l’on recherchera du texte très précis, tandis que la seconde méthode utilise la puissance de l’index pour effectuer une recherche de type “moteur de recherche”, renvoyant des résultats proches de ce qui a été demandé. Ici, comme on s’intéresse uniquement au index, nous ne développerons que la seconde méthode.

  • Création d’un index textuel

Il existe deux manières de créer un index textuel, sur un attribut précis ou alors sur l’ensemble des attributs :

Pour un attribut précis, ici “cle” :

db.coll.createIndex({"cle" : "text"})

Pour tous les attributs :

db.nomDeLaCollection.createIndex({"$**" : "text"})
  • Requêtes avancées utilisant un index textuel

Pour effectuer un requête de type “moteur de recherche”, on utilise la forme suivante :

db.nomDeLaCollection.find({$text : {$search : "ma requête"}})

On remarque plusieurs choses : tout d’abord, il n’est pas nécessaire de préciser le ou les champ sur lequel on veut effectuer la recherche. Ce type de requête n’était possible que sur les champs avec un index textuel, c’est sur ces derniers que le langage va requêter (c’est le sens du "$text"). Ensuite, on remarque la présence de "$search", nécessaire pour ce type de requête.

Par défaut, lorsque l’on effectue une requête contenant plusieurs termes, un OU logique est effectué : les résultats retournés sont ceux qui contiennent au moins l’un des termes. On peut également effectuer une requête impliquant une expression exacte, qui sera encadrée de guillemets échappés par un caractère “” :

db.nomDeLaCollection.find({$text : {$search : "\"ma requête\""}})

De plus, il est possible d’exclure des termes des résultats en utilisant “-“, dans ce cas, un ET logique est effectué. Par exemple, dans la requête suivante, on souhaite les documents contenant “ma requête” et ne contenant pas “exemple” en même temps :

db.nomDeLaCollection.find({$text : {$search : "ma requête -exemple"}})

Enfin, on peut classer les documents par pertinence par rapport à notre requête, en utilisant le score td-idf (plus d’informations disponibles ici :

db.nomDeLaCollection.find({$text: {$search: "ma requête"}},{"score": {$meta: "textScore"}}).sort({score: {$meta: "textScore"}})

Cette requête renvoie une liste des documents ordonnée par pertinence, si vous souhaitez juste afficher le score de chaque document, il suffit d’enlever .sort({score: {$meta: "textScore"}}).

Exemple 1 : Liste des documents comportant le terme “famille” mais pas le terme “politique”.

use discours

db.discours.find({$text : {$search : "famille -politique"}})
Error: error: {
	"ok" : 0,
	"errmsg" : "text index required for $text query (no such collection 'food.discours')",
	"code" : 27,
	"codeName" : "IndexNotFound"
}

Exemple 2 : Liste ordonnée par pertinence des documents par rapport au terme “écologie” :

db.discours.find({$text: {$search: "écologie"}},{"name": true, "score": {$meta: "textScore"}}).sort({score: {$meta: "textScore"}})
Error: error: {
	"ok" : 0,
	"errmsg" : "text index required for $text query (no such collection 'food.discours')",
	"code" : 27,
	"codeName" : "IndexNotFound"
}

4.6. Index géo-spatiaux

Avec des données géo-spatiales (longitude, latitude), il est possible de créer un index géo-spatial. En plus d’une meilleure efficacité, cet index va permettre de trouver des éléments proches d’un point donné ou bien trouver des éléments inclus dans un polygone.

  • Création d’un index

Pour créer un index géo-spatial il faut lui donner le type “2dsphere” :

db.coll.createIndex({"att" : "2dsphere"})
  • Requêtes avancées

Pour obtenir les éléments les plus proches d’un point on définit d’abord une variable de type “Point” avec ses coordonnées.

Le mot-clé $near est nécessaire:

var ref = {"type": "Point", "coordinates": [longitude, latitude]}
db.nomDeLaCollection.find({"clé": {$near : {$geometry : ref}}})

Exemple 1 :

use food
switched to db food
var CrownHeights= {"type": "Point", "coordinates": [-73.923, 40.676]}
db.NYfood.find({"address.loc" : {$near: {$geometry: CrownHeights}}})
{
	"_id" : ObjectId("62309ad719b1d4e452b55208"),
	"address" : {
		"building" : "372",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-73.9220296,
				40.6762625
			]
		},
		"street" : "Ralph Ave",
		"zipcode" : "11233"
	},
	"borough" : "Brooklyn",
	"cuisine" : "Other",
	"grades" : [ ],
	"name" : "Xcellent Soul Food",
	"restaurant_id" : "50018528"
}
{
	"_id" : ObjectId("62309ad719b1d4e452b52e1c"),
	"address" : {
		"building" : "1994",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-73.92211809999999,
				40.6766672
			]
		},
		"street" : "Atlantic Avenue",
		"zipcode" : "11233"
	},
	"borough" : "Brooklyn",
	"cuisine" : "American ",
	"grades" : [
		{
			"date" : ISODate("2014-05-16T00:00:00Z"),
			"grade" : "A",
			"score" : 3
		},
		{
			"date" : ISODate("2013-06-03T00:00:00Z"),
			"grade" : "A",
			"score" : 11
		},
		{
			"date" : ISODate("2012-06-16T00:00:00Z"),
			"grade" : "A",
			"score" : 7
		}
	],
	"name" : "Popeyes",
	"restaurant_id" : "41657236"
}
{
	"_id" : ObjectId("62309ad619b1d4e452b4ffe5"),
	"address" : {
		"building" : "1883",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-73.9225428,
				40.6773249
			]
		},
		"street" : "Atlantic Avenue",
		"zipcode" : "11233"
	},
	"borough" : "Brooklyn",
	"cuisine" : "Hamburgers",
	"grades" : [
		{
			"date" : ISODate("2014-10-09T00:00:00Z"),
			"grade" : "A",
			"score" : 11
		},
		{
			"date" : ISODate("2013-09-17T00:00:00Z"),
			"grade" : "A",
			"score" : 9
		},
		{
			"date" : ISODate("2013-04-22T00:00:00Z"),
			"grade" : "A",
			"score" : 12
		},
		{
			"date" : ISODate("2012-11-29T00:00:00Z"),
			"grade" : "A",
			"score" : 11
		},
		{
			"date" : ISODate("2011-11-10T00:00:00Z"),
			"grade" : "A",
			"score" : 0
		}
	],
	"name" : "Mcdonald'S",
	"restaurant_id" : "40946431"
}
{
	"_id" : ObjectId("62309ad719b1d4e452b537f5"),
	"address" : {
		"building" : "433A",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-73.92194060000001,
				40.6743341
			]
		},
		"street" : "Ralph Avenue",
		"zipcode" : "11233"
	},
	"borough" : "Brooklyn",
	"cuisine" : "Chinese",
	"grades" : [
		{
			"date" : ISODate("2014-06-02T00:00:00Z"),
			"grade" : "A",
			"score" : 0
		},
		{
			"date" : ISODate("2013-05-14T00:00:00Z"),
			"grade" : "A",
			"score" : 2
		}
	],
	"name" : "Dong Fang Chinese Food",
	"restaurant_id" : "41720441"
}
{
	"_id" : ObjectId("62309ad719b1d4e452b52dad"),
	"address" : {
		"building" : "431",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-73.921791,
				40.674391
			]
		},
		"street" : "Ralph Avenue",
		"zipcode" : "11233"
	},
	"borough" : "Brooklyn",
	"cuisine" : "Other",
	"grades" : [
		{
			"date" : ISODate("2014-06-03T00:00:00Z"),
			"grade" : "A",
			"score" : 2
		},
		{
			"date" : ISODate("2013-05-31T00:00:00Z"),
			"grade" : "A",
			"score" : 9
		},
		{
			"date" : ISODate("2012-05-30T00:00:00Z"),
			"grade" : "A",
			"score" : 12
		}
	],
	"name" : "Crown Fried Chicken",
	"restaurant_id" : "41653409"
}
{
	"_id" : ObjectId("62309ad619b1d4e452b5166a"),
	"address" : {
		"building" : "1928",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-73.922004,
				40.678618
			]
		},
		"street" : "Fulton Street",
		"zipcode" : "11233"
	},
	"borough" : "Brooklyn",
	"cuisine" : "Caribbean",
	"grades" : [
		{
			"date" : ISODate("2014-12-15T00:00:00Z"),
			"grade" : "Z",
			"score" : 17
		},
		{
			"date" : ISODate("2014-07-29T00:00:00Z"),
			"grade" : "A",
			"score" : 8
		},
		{
			"date" : ISODate("2013-12-11T00:00:00Z"),
			"grade" : "A",
			"score" : 10
		},
		{
			"date" : ISODate("2013-07-01T00:00:00Z"),
			"grade" : "B",
			"score" : 23
		},
		{
			"date" : ISODate("2012-11-27T00:00:00Z"),
			"grade" : "B",
			"score" : 23
		}
	],
	"name" : "Trini Home Restaurant",
	"restaurant_id" : "41408013"
}
{
	"_id" : ObjectId("62309ad719b1d4e452b51a85"),
	"address" : {
		"building" : "1884",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-73.923975,
				40.678735
			]
		},
		"street" : "Fulton Street",
		"zipcode" : "11233"
	},
	"borough" : "Brooklyn",
	"cuisine" : "Chinese",
	"grades" : [
		{
			"date" : ISODate("2014-04-23T00:00:00Z"),
			"grade" : "A",
			"score" : 6
		},
		{
			"date" : ISODate("2013-11-19T00:00:00Z"),
			"grade" : "A",
			"score" : 9
		},
		{
			"date" : ISODate("2013-05-21T00:00:00Z"),
			"grade" : "B",
			"score" : 17
		},
		{
			"date" : ISODate("2012-11-27T00:00:00Z"),
			"grade" : "B",
			"score" : 23
		},
		{
			"date" : ISODate("2012-09-17T00:00:00Z"),
			"grade" : "A",
			"score" : 13
		},
		{
			"date" : ISODate("2011-09-07T00:00:00Z"),
			"grade" : "A",
			"score" : 10
		}
	],
	"name" : "Lee'S Kitchen",
	"restaurant_id" : "41462031"
}
{
	"_id" : ObjectId("62309ad719b1d4e452b538ad"),
	"address" : {
		"building" : "391",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-73.91948359999999,
				40.674246
			]
		},
		"street" : "Howard Avenue",
		"zipcode" : "11233"
	},
	"borough" : "Brooklyn",
	"cuisine" : "Other",
	"grades" : [
		{
			"date" : ISODate("2014-04-18T00:00:00Z"),
			"grade" : "A",
			"score" : 5
		}
	],
	"name" : "The Ooh Lala  Lounge",
	"restaurant_id" : "50000096"
}
{
	"_id" : ObjectId("62309ad719b1d4e452b53f3c"),
	"address" : {
		"building" : "479",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-73.9219035,
				40.6729038
			]
		},
		"street" : "Ralph Avenue",
		"zipcode" : "11233"
	},
	"borough" : "Brooklyn",
	"cuisine" : "Chinese",
	"grades" : [
		{
			"date" : ISODate("2014-09-02T00:00:00Z"),
			"grade" : "B",
			"score" : 18
		},
		{
			"date" : ISODate("2013-12-11T00:00:00Z"),
			"grade" : "B",
			"score" : 27
		}
	],
	"name" : "No. 1 Chinese Restaurant",
	"restaurant_id" : "50003206"
}
{
	"_id" : ObjectId("62309ad719b1d4e452b53574"),
	"address" : {
		"building" : "17",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-73.9216929,
				40.6792662
			]
		},
		"street" : "Macdougal Street",
		"zipcode" : "11233"
	},
	"borough" : "Brooklyn",
	"cuisine" : "American ",
	"grades" : [
		{
			"date" : ISODate("2014-03-26T00:00:00Z"),
			"grade" : "A",
			"score" : 9
		},
		{
			"date" : ISODate("2013-03-13T00:00:00Z"),
			"grade" : "A",
			"score" : 13
		}
	],
	"name" : "Crown Fried Chicken",
	"restaurant_id" : "41707416"
}
Type "it" for more

Si l’on veut trouver les éléments inclus dans un polygone la variable sera de type “Polygon” et aura plusieurs couples de coordonnées. Pour avoir un polygone fermé, il faudra veiller à ce que les dernières coordonnées soient égales aux premières.

Le mot-clé $within remplace ici $near :

var ref = {"type": "Polygon", "coordinates": [[[long1, lat1],
                                                 [long2, lat2],
                                                 [long3, lat3],
                                                 [long4, lat4],
                                                 [long1, lat1]]]}
db.nomDeLaCollection.find({"clé": {$within : {$geometry : ref}}})                                                 

Exemple 2 :

var eastVillage= {"type" : "Polygon", "coordinates" : [[[-73.9917900, 40.7264100],
                                                    [-73.9917900, 40.7321400],
                                                    [-73.9829300, 40.7321400],
                                                    [-73.9829300, 40.7264100],
                                                    [-73.9917900, 40.7264100]]]}
db.NYfood.find({"address.loc": {$within : {$geometry : eastVillage}}})
{
	"_id" : ObjectId("62309ad719b1d4e452b516e3"),
	"address" : {
		"building" : "347",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-73.98294899999999,
				40.7317368
			]
		},
		"street" : "East 14 Street",
		"zipcode" : "10003"
	},
	"borough" : "Manhattan",
	"cuisine" : "Thai",
	"grades" : [
		{
			"date" : ISODate("2014-02-26T00:00:00Z"),
			"grade" : "A",
			"score" : 12
		},
		{
			"date" : ISODate("2012-12-20T00:00:00Z"),
			"grade" : "A",
			"score" : 7
		},
		{
			"date" : ISODate("2011-12-16T00:00:00Z"),
			"grade" : "A",
			"score" : 12
		},
		{
			"date" : ISODate("2011-08-15T00:00:00Z"),
			"grade" : "A",
			"score" : 10
		},
		{
			"date" : ISODate("2011-06-13T00:00:00Z"),
			"grade" : "P",
			"score" : 0
		}
	],
	"name" : "Kati Thai Cuisine",
	"restaurant_id" : "41415537"
}
{
	"_id" : ObjectId("62309ad619b1d4e452b50faf"),
	"address" : {
		"building" : "233",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-73.9829827,
				40.7311945
			]
		},
		"street" : "1 Avenue",
		"zipcode" : "10003"
	},
	"borough" : "Manhattan",
	"cuisine" : "Chicken",
	"grades" : [
		{
			"date" : ISODate("2014-08-06T00:00:00Z"),
			"grade" : "A",
			"score" : 8
		},
		{
			"date" : ISODate("2013-07-27T00:00:00Z"),
			"grade" : "A",
			"score" : 11
		},
		{
			"date" : ISODate("2012-11-21T00:00:00Z"),
			"grade" : "B",
			"score" : 17
		},
		{
			"date" : ISODate("2012-05-15T00:00:00Z"),
			"grade" : "C",
			"score" : 41
		}
	],
	"name" : "Big Arc Chicken",
	"restaurant_id" : "41312502"
}
{
	"_id" : ObjectId("62309ad619b1d4e452b5015e"),
	"address" : {
		"building" : "210",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-73.9829479,
				40.73032
			]
		},
		"street" : "1 Avenue",
		"zipcode" : "10009"
	},
	"borough" : "Manhattan",
	"cuisine" : "Latin (Cuban, Dominican, Puerto Rican, South & Central American)",
	"grades" : [
		{
			"date" : ISODate("2014-06-12T00:00:00Z"),
			"grade" : "A",
			"score" : 9
		},
		{
			"date" : ISODate("2014-01-31T00:00:00Z"),
			"grade" : "A",
			"score" : 9
		},
		{
			"date" : ISODate("2013-07-29T00:00:00Z"),
			"grade" : "A",
			"score" : 9
		},
		{
			"date" : ISODate("2013-02-25T00:00:00Z"),
			"grade" : "A",
			"score" : 13
		},
		{
			"date" : ISODate("2012-09-11T00:00:00Z"),
			"grade" : "A",
			"score" : 11
		},
		{
			"date" : ISODate("2012-04-18T00:00:00Z"),
			"grade" : "B",
			"score" : 20
		}
	],
	"name" : "Gena'S Grill",
	"restaurant_id" : "40996589"
}
{
	"_id" : ObjectId("62309ad719b1d4e452b51fd8"),
	"address" : {
		"building" : "210",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-73.9829479,
				40.73032
			]
		},
		"street" : "1 Avenue",
		"zipcode" : "10009"
	},
	"borough" : "Manhattan",
	"cuisine" : "Pizza",
	"grades" : [
		{
			"date" : ISODate("2014-10-01T00:00:00Z"),
			"grade" : "A",
			"score" : 8
		},
		{
			"date" : ISODate("2014-02-07T00:00:00Z"),
			"grade" : "B",
			"score" : 19
		},
		{
			"date" : ISODate("2013-06-05T00:00:00Z"),
			"grade" : "A",
			"score" : 9
		},
		{
			"date" : ISODate("2012-12-19T00:00:00Z"),
			"grade" : "A",
			"score" : 10
		},
		{
			"date" : ISODate("2011-12-06T00:00:00Z"),
			"grade" : "A",
			"score" : 2
		}
	],
	"name" : "Papa John'S Pizza",
	"restaurant_id" : "41531418"
}
{
	"_id" : ObjectId("62309ad719b1d4e452b51a57"),
	"address" : {
		"building" : "208",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-73.983001,
				40.73025
			]
		},
		"street" : "1 Avenue",
		"zipcode" : "10009"
	},
	"borough" : "Manhattan",
	"cuisine" : "Mediterranean",
	"grades" : [
		{
			"date" : ISODate("2015-01-07T00:00:00Z"),
			"grade" : "Z",
			"score" : 43
		},
		{
			"date" : ISODate("2014-04-15T00:00:00Z"),
			"grade" : "A",
			"score" : 11
		},
		{
			"date" : ISODate("2013-08-19T00:00:00Z"),
			"grade" : "A",
			"score" : 5
		},
		{
			"date" : ISODate("2013-03-07T00:00:00Z"),
			"grade" : "C",
			"score" : 37
		},
		{
			"date" : ISODate("2012-05-07T00:00:00Z"),
			"grade" : "A",
			"score" : 13
		}
	],
	"name" : "Balade",
	"restaurant_id" : "41460032"
}
{
	"_id" : ObjectId("62309ad619b1d4e452b4f423"),
	"address" : {
		"building" : "141",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-73.98299,
				40.72726
			]
		},
		"street" : "Avenue A",
		"zipcode" : "10009"
	},
	"borough" : "Manhattan",
	"cuisine" : "American ",
	"grades" : [
		{
			"date" : ISODate("2015-01-05T00:00:00Z"),
			"grade" : "A",
			"score" : 12
		},
		{
			"date" : ISODate("2014-06-25T00:00:00Z"),
			"grade" : "A",
			"score" : 2
		},
		{
			"date" : ISODate("2013-03-11T00:00:00Z"),
			"grade" : "A",
			"score" : 13
		},
		{
			"date" : ISODate("2012-02-28T00:00:00Z"),
			"grade" : "A",
			"score" : 11
		}
	],
	"name" : "Doc Holidays",
	"restaurant_id" : "40398690"
}
{
	"_id" : ObjectId("62309ad719b1d4e452b53750"),
	"address" : {
		"building" : "139",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-73.982969,
				40.7271749
			]
		},
		"street" : "Avenue A",
		"zipcode" : "10009"
	},
	"borough" : "Manhattan",
	"cuisine" : "American ",
	"grades" : [
		{
			"date" : ISODate("2014-04-08T00:00:00Z"),
			"grade" : "A",
			"score" : 5
		},
		{
			"date" : ISODate("2013-04-04T00:00:00Z"),
			"grade" : "A",
			"score" : 2
		}
	],
	"name" : "Sustainable Nyc",
	"restaurant_id" : "41717412"
}
{
	"_id" : ObjectId("62309ad619b1d4e452b506c3"),
	"address" : {
		"building" : "125",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-73.9892102,
				40.7317679
			]
		},
		"street" : "East   11 Street",
		"zipcode" : "10003"
	},
	"borough" : "Manhattan",
	"cuisine" : "American ",
	"grades" : [
		{
			"date" : ISODate("2014-02-13T00:00:00Z"),
			"grade" : "A",
			"score" : 13
		},
		{
			"date" : ISODate("2012-12-20T00:00:00Z"),
			"grade" : "A",
			"score" : 8
		},
		{
			"date" : ISODate("2012-04-20T00:00:00Z"),
			"grade" : "C",
			"score" : 33
		},
		{
			"date" : ISODate("2011-07-08T00:00:00Z"),
			"grade" : "A",
			"score" : 10
		}
	],
	"name" : "Webster Hall Studio",
	"restaurant_id" : "41145020"
}
{
	"_id" : ObjectId("62309ad619b1d4e452b50947"),
	"address" : {
		"building" : "64",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-73.9889218,
				40.7313146
			]
		},
		"street" : "3 Avenue",
		"zipcode" : "10003"
	},
	"borough" : "Manhattan",
	"cuisine" : "American ",
	"grades" : [
		{
			"date" : ISODate("2014-12-18T00:00:00Z"),
			"grade" : "Z",
			"score" : 30
		},
		{
			"date" : ISODate("2014-07-14T00:00:00Z"),
			"grade" : "A",
			"score" : 13
		},
		{
			"date" : ISODate("2014-01-14T00:00:00Z"),
			"grade" : "A",
			"score" : 13
		},
		{
			"date" : ISODate("2013-05-20T00:00:00Z"),
			"grade" : "B",
			"score" : 20
		},
		{
			"date" : ISODate("2012-11-13T00:00:00Z"),
			"grade" : "B",
			"score" : 18
		},
		{
			"date" : ISODate("2012-06-18T00:00:00Z"),
			"grade" : "A",
			"score" : 10
		}
	],
	"name" : "Village Pourhouse",
	"restaurant_id" : "41200236"
}
{
	"_id" : ObjectId("62309ad619b1d4e452b4f323"),
	"address" : {
		"building" : "85",
		"loc" : {
			"type" : "Point",
			"coordinates" : [
				-73.9899313,
				40.731505
			]
		},
		"street" : "4 Avenue",
		"zipcode" : "10003"
	},
	"borough" : "Manhattan",
	"cuisine" : "American ",
	"grades" : [
		{
			"date" : ISODate("2014-10-27T00:00:00Z"),
			"grade" : "A",
			"score" : 12
		},
		{
			"date" : ISODate("2013-09-19T00:00:00Z"),
			"grade" : "A",
			"score" : 12
		},
		{
			"date" : ISODate("2012-09-17T00:00:00Z"),
			"grade" : "A",
			"score" : 8
		}
	],
	"name" : "Amsterdam Billiards",
	"restaurant_id" : "40393154"
}
Type "it" for more