1 . 覆盖索引查询
所有的查询字段都是索引的一部分;所有的查询返回字段在同一个索引中。
由于索引存在于 RAM 中,因而从索引中获取数据要比扫描文档更快。
范例:
创建如下 users 集合(使用前面所学的方法创建该集合):
{
"contact": "987654321",
"dob": "01-01-1991",
"gender": "M",
"name": "Tom Benzamin",
"user_name": "tombenzamin"
}
在 users 中创建一个联合索引:
> db.users.ensureIndex({gender:1,user_name:1})
该索引会覆盖下面的查询:
> db.users.find({gender:"M"},{user_name:1,_id:0})
对于上述查询,MongoDB 不会在数据库文件中查找,而会从索引中提取数据。因为索引中不包含 _id 字段,所以 _id 在查询中会默认返回,可以在查询结果中将其排除。而 db.users.find({gender:"M"},{user_name:1})
就不会被索引覆盖。
2 . 索引
创建如下 users 集合(使用前面所学的方法创建该集合):
{
"address": {
"city": "chengdu",
"province": "sichuan",
"pincode": "123"
},
"tags": [
"music",
"cricket",
"blogs"
],
"name": "clound"
}
索引数组字段,在数组中创建索引,需要对数组中的每个字段依次建立索引。所以在我们为数组 tags 创建索引时,会为 music、cricket、blogs 三个值建立单独的索引。
范例:
> db.users.ensureIndex({"tags":1})
创建索引后,我们可以这样检索集合的 tags 字段:
> db.users.find({tags:"cricket"})
为了验证我们使用了索引,可以使用 explain 命令:
> db.users.find({tags:"cricket"}).explain()
2.1 索引子文档字段
假设我们需要通过 city、province、pincode 字段来检索文档,由于这些字段是子文档的字段,所以我们需要对子文档建立索引。
范例:
为子文档的三个字段创建索引,命令如下:
> db.users.ensureIndex({"address.city":1,"address.province":1,"address.pincode":1})
一旦创建索引,我们可以使用子文档的字段来检索数据:
> db.users.find({"address.city":"chengdu"})
记住查询表达式必须遵循指定的索引的顺序。所以上面创建的索引将支持以下查询:
> db.users.find({"address.city":"chengdu","address.province":"sichuan"})
同样支持以下查询:
> db.users.find({"address.city":"chengdu","address.province":"sichuan","address.pincode":"123"})
3 . 原子操作
所谓原子操作,就是要么执行成功,要么执行失败,执行成功完成既定任务,执行失败还原执行前的状态。
常用原子操作命令:
3.1 $set
用来指定一个键并更新键值,若键不存在则创建。
{ $set : { field : value } }
3.2 $unset
用来删除一个键。
{ $unset : { field : 1} }
3.3 $inc
$inc 可以对文档的某个值为数字型(只能为满足要求的数字)的键进行增减的操作。
{ $inc : { field : value } }
3.4 $push
把 value 追加到 field 里面去,field 一定要是数组类型才行,如果 field 不存在,会新增一个数组类型加进去。
{ $push : { field : value } }
3.5 $pushAll
同 $push ,只是一次可以追加多个值到一个数组字段内。
{ $pushAll : { field : value_array } }
3.6 $pull
从数组 field 内删除一个等于 value 值。
{ $pull : { field : _value } }
3.7 $addToSet
增加一个值到数组内,而且只有当这个值不在数组内才增加。
3.8 $pop
删除数组的个或后一个元素。
{ $pop : { field : 1 } }
3.9 $rename
修改字段名称:
{ $rename : { old_field_name : new_field_name } }
3.10 $bit
位操作,integer 类型
{$bit : { field : {and : 5}}}
4 . 查询分析
4.1 explain()
explain()
操作提供了查询信息,使用索引及查询统计等。有利于我们对索引的优化。接下来我们在 users 集合中创建 gender 和 user_name 的索引:
> db.users.ensureIndex({gender:1,user_name:1})
> db.users.find({gender:"M"},{user_name:1,_id:0}).explain()
4.2 hint()
虽然 MongoDB 查询优化器一般工作的很不错,但是也可以使用 hints()
来强迫 MongoDB 使用一个指定的索引。通过这种方法在某些情形下会提升性能。
范例:
指定使用 gender 和 user_name 索引字段来查询:
> db.users.find({gender:"M"},{user_name:1,_id:0}).hint({gender:1,user_name:1})
可以使用 explain()
函数来分析以上查询:
> db.users.find({gender:"M"},{user_name:1,_id:0}).hint({gender:1,user_name:1}).explain()