mongodb:3.4
robomongo:1.0.RC1
执行的语句:
db.urlcontents.find({ir_urltitle:{$regex:"科技"}, ir_groupname:"产业热点" }).sort({ir_urltime:-1}).explain("queryPlanner")
结果为:
{
"cursor" : "BtreeCursor ir_groupname_1_ir_urltime_-1_ir_urltitle_1 multi"-索引名,
"isMultiKey" : false --- 是否使用多键索引,
"n" : 39 --- 返回的文档数量,
"nscannedObjects" : 39 --- Mongodb按照索引指针去磁盘上查找实际文档次数,
"nscanned" : 3103 --- 查找过的索引条目数,
"nscannedObjectsAllPlans" : 3144,
"nscannedAllPlans" : 12424,
"scanAndOrder" : false --- 是否在内存中排序,
"indexOnly" : false --- 是否使用了索引覆盖,
"nYields" : 0 --- 为了让写入请求能够顺利执行,本次查询暂停的次数,
"nChunkSkips" : 0,
"millis" : 36 --- 查询计划花费的总时间,
"indexBounds" : {
"ir_groupname" : [
[
"产业热点",
"产业热点"
]
],
"ir_urltime" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
],
"ir_urltitle" : [
[
"",
{}
],
[
/科技/,
/科技/
]
]
},
"server" : "10-10-114-219:27018"
}
覆盖索引就是:当一个索引包含用户请求的所有字段,可以认为这个索引覆盖了本次查询。
所以在实际中,我们应该优先使用覆盖索引,而不是去获取实际的文档。这样可以保证工作集比较小,尤其与右平衡索引一起使用时。 ——《Mongodb权威指南》
由于mongodb默认返回的字段中包含_id
字段,所以最好使用投射
来指定不要返回_id
。
如果一个查询使用的是覆盖索引,那么执行explain()
时,indexOnly
字段的值为true
。
唯一索引可以确保集合的每一个文档的指定键都有唯一值。例如,如果想保证不同文档的username
键拥有不同的值,创建一个唯一索引就好了:
>db.users.ensureIndex({"username":1},{"unique":true})
如果试图向上面的集合中插入如下文档:
>db.users.insert({username:"bob"})
>db.users.insert({username:"bob"})
会报错:E11000 duplicate key error index : test.users.$username_1 dup key :{:”bob”}
系统自动创建的_id
就是唯一索引,这个唯一索引是不能被删除的,其他唯一索引可以删除。
在上面的基础上,创建多个键的所以即可。
比如:
{username:1, age:1}
>db.test.ensureIndex({email:1},{unique:true, sparse:true})
上面的意思是:创建了一个可选的唯一索引,也就是说,email
这个字段可以没有,如果有,则必须是唯一的,不能重复。而上面唯一索引,即便字段为null或不存在,也不允许重复出现。sparse
选项是用来创建稀疏索引的。
注意:
稀疏索引不必是唯一的。只要去掉unique
选项,就可以创建一个非唯一的稀疏索引。
mongodb查询一般情况下,是一次查询只能使用一个索引,但是$or
是个例外:
假设我们创建了所以{x:1}
和索引{y:1}
db.foo.find({"$or":[{'x':123},{"y":456}]})
这里执行两个索引,因为Mongodb
是执行两次后查询后,把结果合并到一起的。
mongodb索引统一在system.indexes
集合中管理。
这个集合只能通过ensureIndex
和dropIndexes
来操作。
如果索引包含两个以上的键时,指定索引名称会更好看些。
>db.foo.ensureIndex({a:1,b:1,c:1,d:1},{"name":"自己取个名字"})
可以调用getLastError
方法来查看索引是否创建成功。
db.people.getIndexes()
db.people.dropIndex("x_1_y_1")
{"nIndexesWas":3, "ok":1}
索引信息里的name
字段就是该索引的唯一标识
db.people.ensureIndex({x:1,y:1},{background:1})