1

Mongodb多键索引(Multikey Indexes)

Posted by 撒得一地 on 2016年4月10日 in Mongodb教程

为了设置一个存储数组值的字段为索引,MongoDB 为数组中的每个元素创建一个索引键。这些多键索引(multikey indexes)支持针对数组字段的高效查询。如果这个键存储着数组,MongoDB会自动地决定是否需要创建一个多键索引。您不需要显示地指定索引为多键类型。

图中是关于'addr.zip'字段的多键索引。

 

创建多键索引

使用 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

Comments are closed. Would you like to contact the author directly?
网站地图|XML地图

Copyright © 2015-2024 技术拉近你我! All rights reserved.
闽ICP备15015576号-1 版权所有©psz.