请先看下面这个 MongoDB 文档集合(users)示例:

{
"address": {
"city": "Los Angeles",
"state": "California",
"pincode": "123"
},
"tags": [
"music",
"cricket",
"blogs"
],
"name": "Tom Benzamin"
}
该示例文档同时包含了 address 子文档以及 tags 数组字段。
索引数组字段
假设我们需要根据标签来查询用户数据,那么就应该为集合中的 tags 数组字段创建索引。
在 MongoDB 中,为数组字段建立索引时,并不是把整个数组作为一个值进行索引,而是会对数组中的每一个元素分别建立索引。也就是说,当对数组 tags 创建索引后,music、cricket、blogs 这些元素都会各自进入索引,从而提升数组字段查询性能。
可以使用下面的命令创建数组索引:
>db.users.ensureIndex({"tags":1})
索引创建完成后,就可以按如下方式查询集合中的 tags 字段:
>db.users.find({tags:"cricket"})
如果想确认查询是否命中了索引,可以使用 explain 命令进行分析:
>db.users.find({tags:"cricket"}).explain()
如果执行结果中显示 "cursor" : "BtreeCursor tags_1",则说明当前查询已经成功使用了该索引。
索引子文档字段
如果需要通过 city、state、pincode 等字段来检索文档,关键点在于这些字段都位于 address 子文档内部。因此,建立索引时不能只针对顶层文档,而应直接对子文档字段创建索引,这样才能有效提升 MongoDB 查询效率。
为子文档中的这三个字段创建复合索引,命令如下:
>db.users.ensureIndex({"address.city":1,"address.state":1,"address.pincode":1})
创建好索引之后,我们就可以基于子文档字段进行数据检索:
>db.users.find({"address.city":"Los Angeles"})
查询条件的书写顺序不一定要与复合索引中的字段顺序完全一致,MongoDB 会在一定程度上自动进行查询优化。因此,上面创建的索引同样支持下面这种查询方式:
>db.users.find({"address.state":"California","address.city":"Los Angeles"})
此外,它也支持如下更完整的子文档组合查询:
>db.users.find({"address.city":"Los Angeles","address.state":"California","address.pincode":"123"})