单一字段索引
MongoDB对于collection中的任意字段(field)提供了完整的索引支持,在默认情况下,所有collection中的_id 均建立了索引,并且应用和用户也可以增加额外的索引来支持重要的查询和操作。
以下面的代码为例
{ "_id" : ObjectId(...),
"name" : "Alice",
"age" : 27
}
简单的来说,我们如果想给下面的document增加索引,即
db.friends.createIndex( { "name" : 1 } )
内含字段索引
我们可以给内含document的字段添加索引。观察如下数据结构,
{"_id": ObjectId(...),
"name": "John Doe",
"address": {
"street": "Main",
"zipcode": "53511",
"state": "WI"
}
}
我们可以将street,zipcode等看作是一种二维数据结构。即他们是address对象的属性,建立索引也非常简单,访问对象中的属性即可,如下:
db.people.createIndex( { "address.zipcode": 1 } )
内含document索引
我们可以将内含document视作复杂数据类型,当然也可以在此document上建立索引,数据结构如下:
{
_id: ObjectId(...),
metro: {
city: "New York",
state: "NY"
},
name: "Giant Factory"
}
metro字段为内含document,包括了内含字段city和state,我们可以在metro字段直接建立索引,如下:
db.factories.createIndex( { metro: 1 } )
下面的查询利用该字段的索引,精确匹配到如上数据,
db.factories.find( { metro: { city: "New York", state: "NY" } } )
然而,下面的例子却不能匹配到上面的结果。
db.factories.find( { metro: { state: "NY", city: "New York" } } )
组合索引
MongoDB 支持组合索引,一个单一的索引可以绑定多个fields。
注:任何一个组合索引最多可以绑定31个fields
上图中,先按升序建立userid索引,再按降序建立score索引。
例1,
{
"_id": ObjectId(...),
"item": "Banana",
"category": ["food", "produce", "grocery"],
"location": "4th Street Store",
"stock": 4,
"type": "cases",
"arrival": Date(...)
}
如果我们查询item(field) 或者查询item和stock(field),我们可以定义如下的组合索引来加速我们的查询。
db.products.createIndex( { "item": 1, "stock": 1 } )
例2,
我们建立如下查询:
db.events.find().sort( { username: 1, date: -1 } )
db.events.find().sort( { username: -1, date: 1 } )
上面两种排序查询:
- username升序,date降序
- username降序,date升序
可以通过建立如下索引来加速查询
db.events.createIndex( { "username" : 1, "date" : -1 } )
然而,上述先升序再降序索引并不支持username,date全部按升序或降序查询,如下
db.events.find().sort( { username: 1, date: 1 } )
索引前缀
索引前缀可以看作是索引字段的向前包含的子集。例如,我们建立如下索引:
{ "item": 1, "location": 1, "stock": 1 }
这样的索引可以有一下的索引前缀。
- { item: 1 }
- { item: 1, location: 1 }
对于上述的组合索引,MongoDB能够在索引前缀的基础上建立索引来支持查询,MongoDB能够对如下字段使用索引进行查询。
- item 字段
- item和location 字段
- item, location和stock 字段
有item字段作为前缀,MongoDB也能够使用上述建立的索引来支持基于item和stock字段的查询。但是,这样做的查询效率不及仅对item和stock建立的索引。
然而,MongoDB不能使用上述索引来建立除了item字段之外的查询(不满足索引前缀的要求)
- location 字段
- stock 字段
- location 和 stock 字段
多键值索引
给一个含有数组属性的字段建立索引,MongoDB能够为数组中每一个元素建立索引关键字。多键值索引能够对数组字段进行高效的查询,如下图。
上图中,为addr的zip元素建立了索引。
如果任何索引字段是数组类型,那么MongoDB自动建立一个多键值索引,你不需要显式指明多键值的类型。
限制
在一个建立索引的document中,只能包含一个类型为数组的索引字段.
有如下记录,
{ _id: 1, a: [ 1, 2 ], b: [ 1, 2 ], category: "AB - both arrays" }
因为a和b 字段均为数组类型,所以我们不能建立{ a: 1, b: 1 }的组合索引。
但如果collection包含如下的记录,
{ _id: 1, a: [1, 2], b: 1, category: "A array" }
{ _id: 2, a: 1, b: [1, 2], category: "B array" }
那么,{ a: 1, b: 1 }的组合索引可以使用于上面collection中的每一条记录。
在建立了{ a: 1, b: 1 }的组合索引之后,如果我们试图插入一条document其a,b字段均为数组类型,则MongoDB会插入失败。
参考资料
mongodb官方手册,http://docs.mongodb.org/manual/core/index-single/