Mongodb多键索引(Multikey Indexes)
为了设置一个存储数组值的字段为索引,MongoDB 为数组中的每个元素创建一个索引键。这些多键索引(multikey indexes)支持针对数组字段的高效查询。如果这个键存储着数组,MongoDB会自动地决定是否需要创建一个多键索引。您不需要显示地指定索引为多键类型。
创建多键索引
使用 db.collection.createIndex() 方法创建多键索引:
db.coll.createIndex( { <field>: < 1 or -1 > } )
如果任何被索引的字段是一个数组的话,MongoDB 自动创建多键索引,你不需要显式指定 multikey 类型。
索引界限(Index Bounds)
如果索引是多键(multikey),索引边界计算遵循特殊的规则。关于多键索引边界的详细信息,请参阅Multikey Index Bounds(多键索引边界)。
限制
复合多键索引(Compound Multikey Indexes)
对于复合多键索引,每个文档的索引可以最多设置一个索引的字段的值是一个数组。因此,如果文档的多个被索引的字段是一个数组,你将不能创建此复合多键索引。或者,如果已经存在一个复合的多键索引,你不能再插入违反此限制的文档。
实例,假设有一个集合包含了如下文档:
{ _id: 1, a:[1,2], b:[1,2],category:"AB - both arrays"}
你不能创建 { a: 1, b: 1 } 这样的复合多键索引(compound multikey index),因为 a 和 b 字段都是一个数组。
但是,假设一个集合包含了如下文档:
{ _id: 1, a: [1, 2], b: 1, category: "A array" } { _id: 2, a: 1, b: [1, 2], category: "B array" }
对于每个文档来说,这样的复合多键索引 { a: 1, b: 1 } 是允许的,因为在复合多键索引中只有一个字段的值是数组,即文档中没有包含 a 和 b 字段都是数组的情况。在创建了多键复合索引后,如果你尝试插入一个 a 和 b 字段的值都是数组的文档,那么 MongoDB 将会使插入失败。
分片键(Shard Keys)
你不能将多键索引(multikey index)指定为分片键索引(shard key index)。
在2.6版本中发生改变:然而,如果一个分片键索引(shard key index)是一个复合索引的前缀,那么如果这个复合索引的一个其他键(即不在分片索引键内)是一个数组,那么这个复合索引就会成为复合多键索引。
哈希索引(Hashed Indexes)
哈希索引不能是多键(multikey)。
覆盖查询(Covered Queries)
一个多键索引(multikey index)不支持覆盖的查询(covered query)。
数组字段作为一个整体上的查询
当查询筛选器指定一个数组作为整体精确查询时,MongoDB 可以使用多键索引先查询数组的第一个元素,而不必使用多键索引扫描查找整个数组。相反,在使用多键索引来查询包含数组的第一个元素后,MongoDB 检索这些已经符合部分条件的文档,然后再筛选出数组的值与查询指定的值完全一致的文档。
例子,假设有一个名为 inventory 的集合包含了如下文档:
{ _id: 5, type: "food", item: "aaa", ratings: [5,8,9]} { _id: 6, type: "food", item: "bbb", ratings: [5,9]} { _id: 7, type: "food", item: "ccc", ratings: [9,5,8]} { _id: 8, type: "food", item: "ddd", ratings: [9,5]} { _id: 9, type: "food", item: "eee", ratings: [5,9,5]}
集合将 ratings 这个字段设为多键索引(multikey index):
db.inventory.createIndex( { ratings: 1 } )
以下的操作将查询 ratings 字段的值为 [5,9] 的文档:
db.inventory.find( { ratings: [ 5, 9 ] } )
MongoDB 可以通过多键索引查找出 ratings 这个数组中任何位置包含有5这个元素的文档,然后,再检索这些文档,筛选出 ratings 的值完全等于 [5,9] 的这些文档。
实例
索引简单数组
假设一个名为 survey 的集合包含了如下文档:
{ _id: 1, item: "ABC", ratings: [ 2, 5, 9 ] }
将 ratings 字段创建为索引:
db.survey.createIndex( { ratings: 1 } )
因为文档中 ratings 值是一个数组,所以 ratings 是一个多键索引。这个多键索引包含了如下三个索引键,每个指向了同一个文档:
2, 5 和 9.
有内嵌文档的索引数组(Index Arrays with Embedded Documents)
你可以对一个包含内嵌 objects 的数组设置为多键索引,
假设 inventory 集合包含了如下文档:
{ _id: 1, item: "abc", stock: [ { size: "S", color: "red", quantity: 25 }, { size: "S", color: "blue", quantity: 10 }, { size: "M", color: "blue", quantity: 50 } ] } { _id: 2, item: "def", stock: [ { size: "S", color: "blue", quantity: 20 }, { size: "M", color: "blue", quantity: 5 }, { size: "M", color: "black", quantity: 10 }, { size: "L", color: "red", quantity: 2 } ] } { _id: 3, item: "ijk", stock: [ { size: "M", color: "blue", quantity: 15 }, { size: "L", color: "blue", quantity: 100 }, { size: "L", color: "red", quantity: 25 } ] } ...
以下的操作会为 stock.size 和 stock.quantity 字段创建一个多键索引:
db.inventory.createIndex({ "stock.size":1,"stock.quantity":1})
复合多键索引不仅可以支持同时包含两个索引键的查询,还支持仅包含索引键前缀 "stock.size" 的查询,如下所示:
db.inventory.find( { "stock.size": "M" } ) db.inventory.find({ "stock.size":"S","stock.quantity":{$gt:20}})
如果想要更多了解复合索引前缀(compound indexes and prefixes)的内容,可以查看复合索引前缀。
复合多键索引也支持排序操作,比如如下的实例:
db.inventory.find().sort({ "stock.size":1, "stock.quantity":1}) db.inventory.find({"stock.size":"M"}).sort({ "stock.quantity":1}
本文固定地址:http://coderschool.cn/1778.html,转载请注明。
1 Comment
博主是不是搞数据库的!!