何为覆盖查询
在每一个 MongoDB 官方文档中,覆盖查询都具有以下两个特点:
- 查询中的所有字段都属于一个索引;
- 查询所返回的所有字段也都属于同一索引内。
既然查询中的所有字段都属于一个索引,MongoDB 就会利用同一索引,匹配查询集合并返回结果,而不需要实际地查看文档。因为索引存在于 RAM 中,从索引中获取数据要比通过扫描文档获取数据快得多。
使用覆盖查询
为了测试覆盖查询,假设在一个 users 集合中包含下列文档:
{
"_id": ObjectId("53402597d852426020000002"),
"contact": "987654321",
"dob": "01-01-1991",
"gender": "M",
"name": "Tom Benzamin",
"c_time": "2018-10-11",
"user_name": "tombenzamin"
}
下面我们将为 users 集合中的 gender 和 user_name 字段创建一个符合索引。使用下列查询:
>db.users.ensureIndex({c_time:-1,gender:1,user_name:1})
这一索引将覆盖下列查询:
>db.users.find({gender:"M",c_time:"2018-10-11"},{user_name:1,_id:0})
MongoDB 查询数据的语法格式如下:
db.collection.find(query, projection)
query :可选,使用查询操作符指定查询条件
projection :可选,使用投影操作符指定返回的键。默认,查询时返回文档中所有键值, 只需省略该参数即可(默认省略)。
MongoDB的find()方法,在 MongoDB 查询文档中此方法接收的第二个可选参数是要检索的字段列表。
在MongoDB中,当执行find()方法时,它默认将显示文档的所有字段。
为了限制显示的字段,需要将字段列表对应的值设置为1或0。
1用于显示字段,而0用于隐藏字段。
注意:在执行find()方法时,始终都会显示_id字段,如果不想要此字段,则需要将其设置为0。
也就是说,对于上面的查询,MongoDB 不会去查看文档,转而从索引数据中获取所需的数据,这显然要快得多。
既然索引不包含 _id 字段,那么当查询中默认返回 _id 时,我们可以在 MongoDB 的查询结果集中将其排除掉。
下面的查询就不会被覆盖。
>db.users.find({gender:"M"},{user_name:1})
最后,需要记住的是,如果出现下列情况,索引不能覆盖查询:
- 索引字段是数组
- 索引字段是子文档