复合索引(Compound Indexes)
MongoDB 支持复合索引,在集合的文档内,单个索引的结构包含了多个字段 [1] 。下面的关系图,是两个字段作为复合索引的示例︰
图中关于两个字段的复合索引 查询时先按 userid 升序 再按 score 降序。
[1]MongoDB 规定复合索引不能超过31个字段,最多31个字段。
复合索引可以支持对多个字段匹配的查询。
例子
假设有名为 products 的集合包含了如下文档:
{ "_id": ObjectId(...), "item": "Banana", "category": ["food", "produce", "grocery"], "location": "4th Street Store", "stock": 4, "type": "cases", "arrival": Date(...) }
如果应用程序查询了 item 字段 ,有时也需要同时查询了 item 和 stock 这两个字段,你可以设置一个复合索引来支持这些查询:
db.products.createIndex( { "item": 1, "stock": 1 } )
重要
你不能对已经有哈希索引的字段再创建复合索引(compound indexes )。如果你尝试创建一个已经包含哈希索引的字段为复合索引,那么你会收到一个错误。
在复合索引中字段的顺序是非常重要的。在前面的示例中,将包含索引的文档首先按 item 字段升序排序,在 item 字段相同的情况下再按 stock 字段的值进行升序排序。
除了支持匹配索引的所有字段的查询,复合索引可以支持索引字段的前缀匹配的查询。有关详细信息,请参阅前缀。
排序顺序
对于索引存储字段的值,当值为1时为升序排序、值为-1时为降序排序。对于单字段索引,键的排序顺序无关紧要,因为 MongoDB 可以遍历任一方向的索引(正序遍历或倒序遍历)。然而,对于复合索引,排序顺序可以决定索引是否可以支持排序操作。
假设一个 events 集合包含的文档中有 username 字段和 date 字段。应用程序查询要求首先按 username 的值进行升序,然后按 date 的值降序排序,最后返回查询,则应该这样设置索引如 ︰
db.events.find().sort( { username: 1, date: -1 } )
或查询返回的结果首先 username 的值降序,然后按 date 的值升序,如 ︰
db.events.find().sort( { username: -1, date: 1 } )
下面的索引可以同时支持上面的两种排序操作:
db.events.createIndex( { "username" : 1, "date" : -1 } )
然而,上述索引不能支持按 username 的值进行排序升序,然后按 date 值进行升序排序,如下所示︰
db.events.find().sort( { username: 1, date: 1 } )
前缀
索引前缀(Index prefixes)是指字段严格按照索引字段开始顺序的子集。例如,请考虑以下的复合索引 ︰
{ "item": 1, "location": 1, "stock": 1 }
上面的索引有如下的索引前缀(index prefixes):
{ item: 1 } { item: 1, location: 1 }
对于复合索引,MongoDB 可以使用索引来支持索引前缀(index prefixes)查询。这样,MongoDB 可以对下列字段查询时使用索引︰
item 字段, item 字段和 location 字段, item 字段和 location 字段和 stock 字段。
MongoDB 还支持对 item 字段和 stock 字段查询时使用索引,因为 item 字段对应于一个前缀。然而,该索引的查询效率不如仅设置 item 索引字段和只设置 stock 索引字段的查询。
然而,对于以下字段 MongoDB 无法使用索引,因为没有包含 item 字段,下面没有字段有一个对应的索引前缀︰
location 字段, stock 字段,或 location 和 stock 字段.
如果集合中有一个复合索引和前缀索引 (例如 {a:1,b:1} 和 {a:1}),如果两个索引不具有稀疏性或唯一约束,那么你可以删除前缀索引 (例如 {a︰1})。 MongoDB 将在所有情况下,在使用复合索引时就已经先使用了前缀索引。
索引交集
从版本2.6开始, MongoDB可以使用 索引交集 来完整匹配查询。采用复合索引来支持查询还是使用索引交集取决于您的系统的具体情况。
本文固定地址:http://coderschool.cn/1776.html,转载请注明.
3 Comments
背景看着怪怪的。
嗯。之前选模板太草率。。
好吧, 对这些不懂的