This article we are going to share with you the use of MongoDB Index, index is like a book directory, if the search for a content in the absence of the help of the directory, can only look through the entire search, which results in a very low efficiency, if the use of the directory, you can quickly locate the area of the specific content, efficiency will be straight up.
Introduction to Indexes
First open the command line and enter MONGO. The default MongoDB connects to a database named Test.
➜~ MONGO
MongoDB Shell version:2.4.9connecting to:test> show collections>
You can use show Collections/tables to view the database as empty.
Then execute the following code at the MongoDB command line terminal
> for (var i=0;i<100000;i++) {... db.users.insert ({username: ' user ' +i}) ...} > Show collectionssystem.indexesusers>
Looking at the database again. System.indexes and users two tables, which are called indexes, which are new database tables.
So there are 100,000 data in the user table.
> Db.users.find () {"_id": ObjectId ("5694d5da8fad9e319c5b43e4"), "username": "User0"} {"_id": ObjectId ("5694d5da8fa D9e319c5b43e5 ")," username ":" user1 "} {" _id ": ObjectId (" 5694d5da8fad9e319c5b43e6 ")," username ":" User2 "} {" _id ": OBJ Ectid ("5694d5da8fad9e319c5b43e7"), "username": "User3"} {"_id": ObjectId ("5694d5da8fad9e319c5b43e8"), "username": " User4 "} {" _id ": ObjectId (" 5694d5da8fad9e319c5b43e9 ")," username ":" User5 "}
Now you need to find any one of these data, such as
> Db.users.find ({username: ' user1234 '}) {"_id": ObjectId ("5694d5db8fad9e319c5b48b6"), "username": "user1234"}
Found this data successfully found, but need to know more information, need to add explain method
> Db.users.find ({username: ' user1234 '}). Explain () { "cursor": "Basiccursor", "Ismultikey": false, "n ": 1, " nscannedobjects ": 100000, " nscanned ": 100000, " Nscannedobjectsallplans ": 100000, " Nscannedallplans ": 100000, " Scanandorder ": false, " IndexOnly ": false, " Nyields ": 0, " nchunkskips ": 0, " Millis ": $, " Indexbounds ": { }, " server ":" root:27017 "}
There are many parameters, and we are only concerned with the "nscanned": 100000 and "Millis": 30 of these two items.
Nscanned represents the total number of documents that MongoDB scanned during the completion of this query. You can see that each document in the collection is scanned and the total time is 30 milliseconds.
If the data has 10 million, if each query document is traversed once. Well, time is pretty impressive, too.
For such queries, the index is a very good solution.
> Db.users.ensureIndex ({"username": 1})
And then look for user1234.
> Db.users.ensureIndex ({"username": 1}) > Db.users.find ({username: ' user1234 '}). Explain () { "cursor": " Btreecursor username_1 ", " Ismultikey ": false, " n ": 1, " nscannedobjects ": 1, " nscanned ": 1, " Nscannedobjectsallplans ": 1, " Nscannedallplans ": 1, " Scanandorder ": false, " IndexOnly ": false, " Nyields ": 0, " nchunkskips ": 0, " Millis ": 0, " indexbounds ": { " username ": [ [ " user1234 ", " user1234 " ] }, " server ":" root:27017 "}
It's a bit weird, the query is done in an instant because the index only finds one piece of data, not 100,000.
Of course, the use of indexes is also a cost: For each index added, each write operation (insert, UPDATE, DELETE) will take more time. This is because when the data changes, not only will the document be updated, but all indexes on the level collection will be updated as well. Therefore, MongoDB restricts a maximum of 64 indexes per collection. Typically, you should not have more than two indexes on a particular collection.
Little Tricks
If a very general query, or the query creates a performance bottleneck, indexing in a field (such as username) is a good choice. However, it is not an index to the field but to the administrator's query (which is less time consuming than the query).
Composite Index
The values of the indexes are arranged in a certain order, so it is very fast to use the index keys to sort the documents.
Db.users.find (). Sort ({' Age ': 1, ' username ': 1})
Here, according to the order of the age and then according to username sort, so username play a role here is not big. To optimize this sort, you may need to index on age and username.
Db.users.ensureIndex ({' Age ': 1, ' username ': 1})
This creates a composite index (an index built on multiple fields), which is useful if the query condition includes multiple keys.
After a composite index is established, each index entry includes an age field and a username field, and points to the location where the document is stored on disk.
At this point, the age field is arranged in a strictly ascending order, and then in ascending order of username, if they are equal.
Query method
Point Query
Used to query for a single value (although there may be multiple documents that contain this value)
Db.users.find ({' Age ': +}). Sort ({' username ':-1})
Because we have built a composite index, an age of username, the index is used in ascending order (that is, the number 1), when using a point query to find {age:21}, the assumption is still 100,000 data, may be 21 of a lot of people, so will find more than one piece of data. Then sort ({' username ':-1}) sorts the data in reverse order, which is the intention. But let's not forget to index ' username ': 1 is ascending (from small to large), if you want to reverse the order as long as the data from the last index, and then iterate to get the desired results.
The sort direction is not important, and MongoDB can traverse the index in any direction.
In conclusion, composite indexes are very efficient in point queries, which directly locate the age, do not need to sort the results, and return the results.
Multi-valued query (Multi-value-query)
Db.users.find ({' age ': {"$gte": +, "$lte": 30}})
Finds documents that match multiple values. Multi-valued queries can also be understood as multiple point queries.
As above, look for ages between 21 and 30. MONOGDB will use the first key "age" in the index to get the result of the match, and the results are usually sorted in indexed order.
Db.users.find ({' age ': {"$gte": +, "$lte": +}}). Sort ({' username ': 1})
Similar to the previous one, this time you need to sort the results.
In the absence of sort, the result of our query is first based on age equals 21,age equals 22. This sort from small to large, when age equals 21 There are multiple, in the conduct of usernamea-z (0-9) such sorting. So, sort ({' username ': 1}), to sort all the results by name in ascending order, this time it had to be sorted in memory and then returned. Less efficient than the previous high.
Of course, in a very small number of cases, the sort will not take much time.
If the result set is large, for example, more than 32mb,mongodb will refuse to sort through so much data.
There's another solution.
You can also create another index {' username ': 1, ' Age ': 1}, if the username is indexed first, and then sortusername, rather than sorted. However, the search time is long when you need to find the hotties woman with age equal to 21 throughout the document.
But which is more efficient?
If you build multiple indexes, how do you choose which one to use?
Efficiency is a sub-situation, if there is no limit, without sorting but need to search the entire collection time will be far more than the former. However, when returning some data (such as limit (1000)), a new winner is created.
>db.users.find ({' age ': {"$gte": +, "$lte": +}}). sort ({username ': 1}). Limit (+). Hint ({' Age ': 1, ' username ': 1}) Explain () [' Millis ']2031ms >db.users.find ({' age ': {"$gte": +, "$lte": +}}). sort ({username ': 1}). Limit (1000) . Hint ({' username ': 1, ' Age ': 1}). Explain () [' Millis ']181ms
Where you can use hint to specify the index to use.
So this approach is still very advantageous. For example, in the general scenario, we will not take all the data out, just to query the nearest, so this efficiency will be higher.
Index type
Unique index
You can ensure that the specified key for each document in the collection has a unique value.
Db.users.ensureIndex ({' username ': 1, unique:true})
For example, using the Mongoose framework, you can specify unique:true when you define a schema.
If you insert 2 data that is called Zhang San, the second time you insert it will fail. _ID is a unique index and cannot be deleted.
Sparse indexes
Use sparse to create sparse indexes
>db.users.ensureindex ({' Email ': 1}, {' Unique ': true, ' sparse ': true})
Index management
The System.indexes collection contains detailed information for each index
Db.system.indexes.find ()
1.ensureIndex () Creating an index
Db.users.ensureIndex ({' username ': 1})
The background creates an index so that the database can still process read-write requests while it is re-creating the index, specifying the background option.
Db.test.ensureIndex ({"username": 1},{"Background": true})
2.getIndexes () View index
Db.collectionName.getIndexes () db.users.getIndexes () [ { "V": 1, "key": { "_id": 1 }, "ns": "Test.users", "name": "_id_" }, { "V": 1, "key": { "username": 1 }, "ns": "Test . Users ", " name ":" Username_1 " }]
Where the V field is used only internally to identify the index version.
3.dropIndex Deleting an index
> Db.users.dropIndex ("Username_1") {"Nindexeswas": 2, "OK": 1}
Or
Full select Copy put in Notes > Db.users.dropIndex ({"username": 1})
The above content is the use of MongoDB index detailed, I hope to help you.