On this page本页内容
To index a field that holds an array value, MongoDB creates an index key for each element in the array. 为了索引保存数组值的字段,MongoDB为数组中的每个元素创建索引键。These multikey indexes support efficient queries against array fields. 这些多键索引支持对数组字段的高效查询。Multikey indexes can be constructed over arrays that hold both scalar values [1] (e.g. strings, numbers) and nested documents.可以在同时包含标量值[1](例如字符串、数字)和嵌套文档的数组上构造多键索引。
[1] |
To create a multikey index, use the 要创建多键索引,请使用db.collection.createIndex()
method:db.collection.createIndex()
方法:
db.coll.createIndex( { <field>: < 1 or -1 > } )
MongoDB automatically creates a multikey index if any indexed field is an array; you do not need to explicitly specify the multikey type.如果任何索引字段是数组,MongoDB会自动创建多键索引;无需显式指定多键类型。
Changed in version 3.4.在版本3.4中更改。
Starting in MongoDB 3.4, for multikey indexes created using MongoDB 3.4 or later, MongoDB keeps track of which indexed field or fields cause an index to be a multikey index. 从MongoDB 3.4开始,对于使用MongoDB 3.4或更高版本创建的多键索引,MongoDB会跟踪哪些索引字段会导致索引成为多键索引。Tracking this information allows the MongoDB query engine to use tighter index bounds.跟踪此信息允许MongoDB查询引擎使用更严格的索引边界。
If an index is multikey, then computation of the index bounds follows special rules. 如果索引是多键的,则索引边界的计算遵循特殊规则。For details on multikey index bounds, see Multikey Index Bounds.有关多键索引边界的详细信息,请参阅多键索引边界。
For unique indexes, the unique constraint applies across separate documents in the collection rather than within a single document.对于唯一索引,唯一约束适用于集合中的各个文档,而不是单个文档。
Because the unique constraint applies to separate documents, for a unique multikey index, a document may have array elements that result in repeating index key values as long as the index key values for that document do not duplicate those of another document.由于唯一约束适用于单独的文档,因此对于唯一的多键索引,只要文档的索引键值不与另一文档的索引键值重复,文档可能具有导致重复索引键值的数组元素。
For more information, see Unique Constraint Across Separate Documents.有关详细信息,请参阅跨单独文档的唯一约束。
For a compound multikey index, each indexed document can have at most one indexed field whose value is an array. 对于复合多键索引,每个索引文档最多可以有一个值为数组的索引字段。That is:
You cannot create a compound multikey index if more than one to-be-indexed field of a document is an array. 如果一个文档的多个待索引字段是一个数组,则无法创建复合多键索引。For example, consider a collection that contains the following document:例如,考虑包含以下文档的集合:
{ _id: 1, a: [ 1, 2 ], b: [ 1, 2 ], category: "AB - both arrays" }
You cannot create a compound multikey index 无法在集合上创建复合多键索引{ a: 1, b: 1 }
on the collection since both the a
and b
fields are arrays.{ a: 1, b: 1 }
,因为a
和b
字段都是数组。
Or, if a compound multikey index already exists, you cannot insert a document that would violate this restriction.或者,如果复合多键索引已经存在,则不能插入违反此限制的文档。
Consider a collection that contains the following documents:考虑包含以下文档的集合:
{ _id: 1, a: [1, 2], b: 1, category: "A array" } { _id: 2, a: 1, b: [1, 2], category: "B array" }
A compound multikey index 允许使用复合多键索引{ a: 1, b: 1 }
is permissible since for each document, only one field indexed by the compound multikey index is an array; i.e. no document contains array values for both a
and b
fields.{ a: 1, b: 1 }
,因为对于每个文档,只有一个由复合多键索引索引的字段是数组;即,没有文档同时包含a
和b
字段的数组值。
However, after creating the compound multikey index, if you attempt to insert a document where both 但是,在创建复合多键索引后,如果尝试插入a
and b
fields are arrays, MongoDB will fail the insert.a
和b
字段都是数组的文档,MongoDB将无法插入。
If a field is an array of documents, you can index the embedded fields to create a compound index. 如果字段是文档数组,则可以为嵌入的字段编制索引以创建复合索引。For example, consider a collection that contains the following documents:例如,考虑包含以下文档的集合:
{ _id: 1, a: [ { x: 5, z: [ 1, 2 ] }, { z: [ 1, 2 ] } ] } { _id: 2, a: [ { x: 5 }, { z: 4 } ] }
You can create a compound index on 您可以在{ "a.x": 1, "a.z": 1 }
. { "a.x": 1, "a.z": 1 }
上创建复合索引。The restriction where at most one indexed field can be an array also applies.最多一个索引字段可以是数组的限制也适用。
For an example, see Index Arrays with Embedded Documents.例如,请参阅嵌入文档的索引数组。
As a result of changes to sorting behavior on array fields in MongoDB 3.6, when sorting on an array indexed with a multikey index the query plan includes a blocking SORT stage. 由于MongoDB 3.6中对数组字段排序行为的更改,在使用多键索引索引的数组上排序时,查询计划包括阻塞排序阶段。The new sorting behavior may negatively impact performance.新的排序行为可能会对性能产生负面影响。
In a blocking SORT, all input must be consumed by the sort step before it can produce output. 在分块排序中,排序步骤必须先消耗所有输入,然后才能生成输出。In a non-blocking, or indexed sort, the sort step scans the index to produce results in the requested order.在非阻塞或索引排序中,排序步骤扫描索引以按请求的顺序生成结果。
You cannot specify a multikey index as the shard key index.不能将多键索引指定为分片键索引。
However, if the shard key index is a prefix of a compound index, the compound index is allowed to become a compound multikey index if one of the other keys (i.e. keys that are not part of the shard key) indexes an array. 但是,如果分片键索引是复合索引的前缀,则如果其他键之一(即不属于分片键的键)对数组进行索引,则允许复合索引成为复合多键索引。Compound multikey indexes can have an impact on performance.复合多键索引可能会影响性能。
Multikey indexes多键索引 cannot cover queries over array field(s).无法覆盖对数组字段的查询。
However, starting in 3.6, multikey indexes can cover queries over the non-array fields if the index tracks which field or fields cause the index to be multikey. 但是,从3.6开始,如果索引跟踪哪些字段导致索引为多键,则多键索引可以覆盖对非数组字段的查询。Multikey indexes created in MongoDB 3.4 or later on storage engines other than MMAPv1 [3] track this data.MongoDB 3.4或更高版本在除MMAPv1之外的存储引擎上创建的多键索引[3]可跟踪此数据。
[2] | |
When a query filter specifies an exact match for an array as a whole, MongoDB can use the multikey index to look up the first element of the query array but cannot use the multikey index scan to find the whole array. 当查询筛选器为整个数组指定精确匹配时,MongoDB可以使用多键索引来查找查询数组的第一个元素,但不能使用多键索引扫描来查找整个数组。Instead, after using the multikey index to look up the first element of the query array, MongoDB retrieves the associated documents and filters for documents whose array matches the array in the query.相反,在使用多键索引查找查询数组的第一个元素后,MongoDB检索关联的文档并筛选其数组与查询中的数组匹配的文档。
For example, consider an 例如,考虑包含以下文档的inventory
collection that contains the following documents: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 ] }
The collection has a multikey index on the 该集合在ratings
field:ratings
字段上有一个多键索引:
db.inventory.createIndex( { ratings: 1 } )
The following query looks for documents where the 下面的查询查找ratings
field is the array [ 5, 9 ]
:ratings
字段为数组[ 5, 9 ]
的文档:
db.inventory.find( { ratings: [ 5, 9 ] } )
MongoDB can use the multikey index to find documents that have MongoDB可以使用多键索引查找5
at any position in the ratings
array. ratings
数组中任意位置具有5
的文档。Then, MongoDB retrieves these documents and filters for documents whose 然后,MongoDB检索这些文档,并筛选ratings
array equals the query array [ 5, 9 ]
.ratings
数组等于查询数组[ 5, 9 ]
的文档。
$expr
$expr
does not support multikey indexes.不支持多键索引。
Indexes built on MongoDB 3.2 or earlier do not contain the necessary flags to support optimized multikey index use. 基于MongoDB 3.2或更早版本构建的索引不包含支持优化多键索引使用的必要标志。To benefit from the performance enhancements of multikey indexes, you must either:要从多键索引的性能增强中获益,您必须:
db.collection.reIndex()
.db.collection.reIndex()
。Consider a 考虑使用以下文档集合survey
collection with the following document:survey
:
{ _id: 1, item: "ABC", ratings: [ 2, 5, 9 ] }
Create an index on the field 在字段ratings
:ratings
上创建索引:
db.survey.createIndex( { ratings: 1 } )
Since the 由于ratings
field contains an array, the index on ratings
is multikey. ratings
字段包含一个数组,因此ratings
上的索引是多键的。The multikey index contains the following three index keys, each pointing to the same document:多键索引包含以下三个索引键,每个索引键指向同一文档:
2
,5
, and9
.You can create multikey indexes on array fields that contain nested objects.可以在包含嵌套对象的数组字段上创建多键索引。
Consider an 考虑使用以下格式的文档进行inventory
collection with documents of the following form: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 } ] } ...
The following operation creates a multikey index on the 以下操作在stock.size
and stock.quantity
fields:stock.size
和stock.quantity
字段上创建多键索引:
db.inventory.createIndex( { "stock.size": 1, "stock.quantity": 1 } )
The compound multikey index can support queries with predicates that include both indexed fields as well as predicates that include only the index prefix 复合多键索引可以支持包含索引字段和仅包含索引前缀"stock.size"
, as in the following examples:"stock.size"
的谓词的查询,如以下示例所示:
db.inventory.find( { "stock.size": "M" } ) db.inventory.find( { "stock.size": "S", "stock.quantity": { $gt: 20 } } )
For details on how MongoDB can combine multikey index bounds, see Multikey Index Bounds. 有关MongoDB如何组合多键索引边界的详细信息,请参阅多键索引边界。For more information on behavior of compound indexes and prefixes, see compound indexes and prefixes.有关复合索引和前缀行为的更多信息,请参阅复合索引和前缀。
The compound multikey index can also support sort operations, such as the following examples:复合多键索引还可以支持排序操作,例如以下示例:
db.inventory.find( ).sort( { "stock.size": 1, "stock.quantity": 1 } ) db.inventory.find( { "stock.size": "M" } ).sort( { "stock.quantity": 1 } )
For more information on behavior of compound indexes and sort operations, see Use Indexes to Sort Query Results.有关复合索引和排序操作行为的详细信息,请参阅使用索引对查询结果进行排序。