Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subdocument index in mongo

What exactly happens when I call ensureIndex(data) when typical data looks like data:{name: "A",age:"B", job : "C"} ? Will it create a compound index over these three fields or will it create only one index applicable when anything from data is requested or something altogether different ?

like image 933
slezadav Avatar asked May 27 '13 09:05

slezadav


People also ask

What is multi key index?

Multi-key indexes can be used when an index value occurs multiple times within a single document. For example, invoices might have invoice number, customer number, and customer name defined as the first three index fields, each occurring once within a given invoice.

What is Multikey index in MongoDB?

MongoDB allows to index a field that holds an array value by creating an index key for each element in the array, such type of indexing is called Multikey indexes. It supports efficient queries against array fields.

How do I index an array field in MongoDB?

To index a field that holds an array value, MongoDB creates an index key for each element in the array. These multikey indexes support efficient queries against array fields. Multikey indexes can be constructed over arrays that hold both scalar values [1] (e.g. strings, numbers) and nested documents.


1 Answers

You can do either :

> db.collection.ensureIndex({"data.name": 1,"data.age":1, "data.job" : 1}) > db.collection.ensureIndex({"data": 1}) 

This is discussed in the documentation under indexes-on-embedded-fields and indexes on sub documents

The important section of the sub document section is 'When performing equality matches on subdocuments, field order matters and the subdocuments must match exactly.'

This means that the 2 indexes are the same for simple queries .

However, as the sub-document example shows, you can get some interesting results (that you might not expect) if you just index the whole sub-document as opposed to a specific field and then do a comparison operator (like $gte) - if you index a specific sub field you get a less flexible, but potentially more useful index.

It really all depends on your use case.

Anyway, once you have created the index you can check what's created with :

> db.collection.getIndexes() [ {     "v" : 1,     "key" : {         "_id" : 1     },     "ns" : "test.collection",     "name" : "_id_" }, {     "v" : 1,     "key" : {         "data.name" : 1,         "data.age" : 1,         "data.job" : 1     },     "ns" : "test.collection",     "name" : "data.name_1_data.age_1_data.job_1" } 

]

As you can see from the output it created a new key called data.name_1_data.age_1_data.job_1 (the _id_ index is always created).

If you want to test your new index then you can do :

> db.collection.insert({data:{name: "A",age:"B", job : "C"}}) > db.collection.insert({data:{name: "A1",age:"B", job : "C"}}) > db.collection.find({"data.name" : "A"}).explain() {     "cursor" : "BtreeCursor data.name_1_data.age_1_data.job_1",      .... more stuff 

The main thing is that you can see that your new index was used (BtreeCursor data.name_1_data.age_1_data.job_1 in the cursor field is what indicates this is the case). If you see "cursor" : "BasicCursor", then your index was not used.

For more detailed information look here.

like image 184
jimoleary Avatar answered Sep 18 '22 20:09

jimoleary