Docs Home → Develop Applications → MongoDB Manual
Multikey Indexes多键索引
On this page本页内容
Multikey indexes collect and sort data from fields containing array values. 多键索引从包含数组值的字段中集合数据并对其进行排序。Multikey indexes improve performance for queries on array fields.多键索引提高了对数组字段的查询性能。
You do not need to explicitly specify the multikey type. 您不需要显式指定多键类型。When you create an index on a field that contains an array value, MongoDB automatically sets that index to be a multikey index.当您在包含数组值的字段上创建索引时,MongoDB会自动将该索引设置为多键索引。
MongoDB can create multikey indexes over arrays that hold both scalar values (for example, strings and numbers) and embedded documents.MongoDB可以在包含标量值(例如字符串和数字)和嵌入文档的数组上创建多键索引。
To create a multikey index, use the following prototype:要创建多键索引,请使用以下原型:
db.<collection>.createIndex( { <arrayField>: <sortOrder> } )
This image shows a multikey index on the 此图显示addr.zip
field:addr.zip
字段上的多键索引:
Use Cases用例
If your application frequently queries a field that contains an array value, a multikey index improves performance for those queries.如果应用程序经常查询包含数组值的字段,则多键索引可以提高这些查询的性能。
For example, documents in a 例如,students
collection contain a test_scores
field: an array of test scores a student received throughout the semester. students
集合中的文档包含一个test_scores
字段:学生在整个学期中收到的测试分数的数组。You regularly update a list of top students: students who have at least five 你会定期更新一份顶尖学生名单:至少有五个test_scores
greater than 90
.test_scores
超过90
的学生。
You can create an index on the 您可以在test_scores
field to improve performance for this query. test_scores
字段上创建索引,以提高此查询的性能。Because 因为test_scores
contains an array value, MongoDB stores the index as a multikey index.test_scores
包含一个数组值,所以MongoDB将索引存储为一个多键索引。
Get Started起步
To create a multikey index, see:要创建多键索引,请参阅:
Details详细信息
This section describes technical details and limitations for multikey indexes.本节介绍了多键索引的技术细节和限制。
Index Bounds索引边界
The bounds of an index scan define the parts of an index to search during a query. 索引扫描的边界定义了在查询过程中要搜索的索引部分。The computation of multikey index bounds follows special rules. 多键索引边界的计算遵循特殊规则。For details, see Multikey Index Bounds.有关详细信息,请参阅多键索引边界。
Unique Multikey Indexes唯一多键索引
In 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.在唯一的多键索引中,只要文档的索引键值不与另一文档的索引键值重复,文档就可能具有导致重复索引键值的数组元素。
To learn more and see an example of this behavior, see Unique Constraint Across Separate Documents.若要了解更多信息并查看此行为的示例,请参阅跨单独文档的唯一约束。
Compound Multikey Indexes复合多键索引
In a compound multikey index, each indexed document can have at most one indexed field whose value is an array. 在复合多键索引中,每个索引文档最多可以有一个索引字段,其值为数组。Specifically:具体而言:
You cannot create a compound multikey index if more than one field in the index specification is an array.如果索引规范中有多个字段是数组,则不能创建复合多键索引。For example, consider a collection that contains this document:例如,考虑一个包含以下文档的集合:{ _id: 1, scores_spring: [ 8, 6 ], scores_fall: [ 5, 9 ] }
You can't create the compound multikey index不能创建复合多键索引{ scores_spring: 1, scores_fall: 1 }
because both fields in the index are arrays.{ scores_spring: 1, scores_fall: 1 }
,因为索引中的两个字段都是数组。If a compound multikey index already exists, you cannot insert a document that would violate this restriction.如果复合多键索引已经存在,则不能插入违反此限制的文档。Consider a collection that contains these documents:考虑一个包含以下文档的集合:{ _id: 1, scores_spring: [8, 6], scores_fall: 9 }
{ _id: 2, scores_spring: 6, scores_fall: [5, 7] }You can create a compound multikey index您可以创建一个复合多键索引{ scores_spring: 1, scores_fall: 1 }
because for each document, only one field indexed by the compound multikey index is an array.{ scores_spring: 1, scores_fall: 1 }
,因为对于每个文档,只有一个由复合多键指数索引的字段是数组。No document contains array values for both没有文档同时包含scores_spring
andscores_fall
fields.scores_spring
和scores_fall
字段的数组值。However, after you create the compound multikey index, if you attempt to insert a document where both但是,在创建复合多键索引后,如果您试图插入一个scores_spring
andscores_fall
fields are arrays, the insert fails.scores_spring
和scores_fall
字段都是数组的文档,则插入操作将失败。
Sorting排序
When you sort based on an array field that is indexed with a multikey index, the query plan includes a blocking sort stage unless both of the following are true:当您根据使用多键索引进行索引的数组字段进行排序时,除非以下两项均为真,否则查询计划将包括一个阻塞排序阶段:
The index boundaries for all sort fields are所有排序字段的索引边界都是[MinKey, MaxKey]
.[MinKey, MaxKey]
。No boundaries for any multikey-indexed field have the same path prefix as the sort pattern.任何多键索引字段的边界都不具有与排序模式相同的路径前缀。
Shard Keys分片键
You cannot specify a multikey index as a shard key index.不能将多键索引指定为分片键索引。
However, if the shard key index is a prefix of a compound index, the compound index may become a compound multikey index if one of the trailing keys (that are not part of the shard key) indexes an array.但是,如果分片键索引是复合索引的前缀,则如果某个尾随键(不是分片键的一部分)对数组进行索引,则复合索引可能会变成复合多键索引。
Hashed Indexes哈希索引
Hashed indexes哈希索引 cannot be multikey.不能是多键。
Covered Queries涵盖的查询
Multikey indexes cannot cover queries over array fields. 多键索引无法覆盖数组字段上的查询。However, multikey indexes can cover queries over non-array fields if the index tracks which field or fields cause the index to be multikey.但是,如果索引跟踪导致索引为多键的字段,则多键索引可以覆盖对非数组字段的查询。
For example, consider a 例如,考虑具有以下文档的matches
collection with these documents:matches
集合:
db.matches.insertMany( [
{ name: "joe", event: ["open", "tournament"] },
{ name: "bill", event: ["match", "championship"] }
] )
The matches
collection has a compound multikey index on the name
and event
fields:matches
集合在name
字段和event
字段上有一个复合多键索引:
db.matches.createIndex( { name: 1, event: 1 } )
This index is a multikey index because the 此索引是一个多键索引,因为event
field contains array values.event
字段包含数组值。
The multikey index covers the following query, even though the matched field (即使匹配的字段(name
) is not an array:name
)不是数组,多键索引也涵盖以下查询:
db.matches.find( { name: "bill" } )
Because 由于name
field is part of the index prefix, the index covers queries on the name
field. name
字段是索引前缀的一部分,因此索引涵盖了对name
字段的查询。The index cannot cover queries on both 索引不能同时覆盖name
and event
, because multikey indexes cannot cover queries on array fields.name
和event
的查询,因为多键索引不能覆盖数组字段的查询。
Query on an Array Field as a Whole将数组字段作为一个整体进行查询
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 these documents:inventory
集合:
db.inventory.insertMany( [
{ _id: 5, type: "food", item: "apple", ratings: [ 5, 8, 9 ] }
{ _id: 6, type: "food", item: "banana", ratings: [ 5, 9 ] }
{ _id: 7, type: "food", item: "chocolate", ratings: [ 9, 5, 8 ] }
{ _id: 8, type: "food", item: "fish", ratings: [ 9, 5 ] }
{ _id: 9, type: "food", item: "grapes", ratings: [ 5, 9, 5 ] }
] )
The inventory
collection has a multikey index on the ratings
field:inventory
集合在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
The $expr
operator does not support multikey indexes.$expr
运算符不支持多键索引。
Learn More了解更多信息
To learn how MongoDB combines multikey index bounds to improve performance, see Multikey Index Bounds.要了解MongoDB如何组合多键索引边界以提高性能,请参阅多键索引界限。To learn how to query array fields, see:要了解如何查询数组字段,请参阅: