Database Manual / Indexes / Types

Multikey Indexes多键索引

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. If an array contains multiple instances of the same value, the index only includes one entry for the value.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字段上的多键索引:

Diagram of a multikey index on the ``addr.zip`` field. The ``addr`` field contains an array of address documents. The address documents contain the ``zip`` field.

You can create and manage multikey indexes in the UI for deployments hosted in MongoDB Atlas.您可以在MongoDB Atlas中托管的部署的UI中创建和管理多键索引

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. Because test_scores contains an array value, MongoDB stores the index as a multikey index.您可以在test_scores字段上创建索引,以提高此查询的性能。因为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. No document contains array values for both scores_spring and scores_fall fields.您可以创建一个复合多键索引{ scores_spring: 1, scores_fall: 1 },因为对于每个文档,只有一个由复合多键索引索引的字段是数组。没有文档同时包含scores_springscores_fall字段的数组值。

    However, after you create the compound multikey index, if you attempt to insert a document where both scores_spring and scores_fall fields are arrays, the insert fails.但是,在创建复合多键索引后,如果尝试插入一个scores_springscores_fall字段都是数组的文档,则插入失败。

Sorting排序

When you sort based on an array field that is indexed with a multikey index, the query plan includes an in-memory 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 can cover queries when these conditions are met:当满足以下条件时,多键索引可以覆盖查询:

  • The query does not return the array field (meaning the array is not included in the query projection). This means that to cover a query, the multikey index must be compound.查询不返回数组字段(意味着数组不包含在查询投影中)。这意味着要覆盖查询,多键索引必须是复合索引
  • The query does not include $elemMatch.查询不包括$elemMatch
  • The query meets all other covered query requirements.该查询满足所有其他涵盖的查询要求

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 event and name fields:matchs集合在eventname字段上有一个复合多键索引:

db.matches.createIndex( { event: 1, name: 1 } )

The preceding index is multikey because the event field contains array values.前面的索引是多键的,因为event字段包含数组值。

The index covers these queries:该索引涵盖了这些查询:

db.matches.find(
{ event: 'championship' },
{ _id: 0, name: 1 }
)

db.matches.find(
{ name: 'Bill', event: 'championship' },
{ _id: 0, name: 1 }
)

The index does not cover the following query because the projection contains the event array field:该索引不包含以下查询,因为投影包含event数组字段:

db.matches.find(
{ event: 'championship' },
{ _id: 0, event: 1 }
)

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 5 at any position in the ratings array. Then, MongoDB retrieves these documents and filters for documents whose ratings array equals the query array [ 5, 9 ].MongoDB可以使用多键索引来查找ratings数组中任何位置都有5的文档。然后,MongoDB检索这些文档,并筛选其ratings数组等于查询数组[5,9]的文档。

$expr

The $expr operator does not support multikey indexes.$expr运算符不支持多键索引。

Learn More了解更多