Compound Indexes复合索引
On this page
MongoDB supports compound indexes, where a single index structure holds references to multiple fields [1] within a collection's documents. MongoDB支持复合索引,其中单个索引结构包含对集合文档中多个字段[1]的引用。The following diagram illustrates an example of a compound index on two fields:下图显示了两个字段上的复合索引示例:
[1] |
Compound indexes can support queries that match on multiple fields.复合索引可以支持在多个字段上匹配的查询。
Create a Compound Index创建复合索引
To create a compound index use an operation that resembles the following prototype:要创建复合索引,请使用类似于以下原型的操作:
db.collection.createIndex( { <field1>: <type>, <field2>: <type2>, ... } )
The value of the field in the index specification describes the kind of index for that field. 索引规范中字段的值描述了该字段的索引类型。For example, a value of 例如,值1
specifies an index that orders items in ascending order. 1
指定按升序排列项目的索引。A value of 值-1指定按降序排列项目的索引。-1
specifies an index that orders items in descending order. For additional index types, see index types.有关其他索引类型,请参阅索引类型。
The order of the indexed fields has a strong impact on the effectiveness of a particular index for a given query. 索引字段的顺序对给定查询的特定索引的有效性有很大影响。For most compound indexes, following the ESR (Equality, Sort, Range) rule helps to create efficient indexes.对于大多数复合索引,遵循ESR(相等、排序、范围)规则有助于创建高效的索引。
Starting in MongoDB 4.4:从MongoDB 4.4开始:
-
Compound indexes may contain a single hashed index field.复合索引可以包含单个哈希索引字段。 -
You will receive an error if you attempt to create a compound index that contains more than one hashed index field.如果您试图创建包含多个哈希索引字段的复合索引,则会收到一个错误。
In MongoDB 4.2 or earlier:在MongoDB 4.2或更早版本中:
-
Compound indexes may not contain a hashed index field.复合索引不能包含哈希索引字段。 -
You will receive an error if you attempt to create a compound index that contains a hashed index field.如果您试图创建包含哈希索引字段的复合索引,则会收到一个错误。
Consider a collection named 考虑一个名为products
that holds documents that resemble the following document:products
的集合,该集合包含与以下文档相似的文档:
{
"_id": ObjectId(...),
"item": "Banana",
"category": ["food", "produce", "grocery"],
"location": "4th Street Store",
"stock": 4,
"type": "cases"
}
The following operation creates an ascending index on the 以下操作在item
and stock
fields:item
和stock
字段上创建升序索引:
db.products.createIndex( { "item": 1, "stock": 1 } )
The order of the fields listed in a compound index is important. 复合索引中列出的字段的顺序很重要。The index will contain references to documents sorted first by the values of the 索引将包含对文档的引用,这些文档首先按item
field and, within each value of the item
field, sorted by values of the stock field. See Sort Order for more information.item
字段的值排序,在item
字段的每个值中,按stock
字段的值排列。有关详细信息,请参阅排序顺序。
In addition to supporting queries that match on all the index fields, compound indexes can support queries that match on the prefix of the index fields. 除了支持所有索引字段匹配的查询外,复合索引还可以支持索引字段前缀匹配的查询。That is, the index supports queries on the 也就是说,该索引支持对项目字段以及item
field as well as both item
and stock
fields:item
和stock
字段的查询:
db.products.find( { item: "Banana" } )
db.products.find( { item: "Banana", stock: { $gt: 5 } } )
For details, see Prefixes.有关详细信息,请参阅前缀。
Sort Order排序顺序
Indexes store references to fields in either ascending (索引以升序(1
) or descending (-1
) sort order. 1
)或降序(-1
)存储对字段的引用。For single-field indexes, the sort order of keys doesn't matter because MongoDB can traverse the index in either direction. 对于单字段索引,键的排序顺序无关紧要,因为MongoDB可以在任意方向遍历索引。However, for compound indexes, sort order can matter in determining whether the index can support a sort operation.但是,对于复合索引,排序顺序在确定索引是否支持排序操作时可能很重要。
Consider a collection 考虑一个包含字段为events
that contains documents with the fields username
and date
. username
和date
的文档的集合events
。Applications can issue queries that return results sorted first by ascending 应用程序可以发出查询,返回的结果首先按username
values and then by descending (i.e. more recent to last) date
values, such as:username
值升序排序,然后按date
值降序排序(即从最近到最后),例如:
db.events.find().sort( { username: 1, date: -1 } )
or queries that return results sorted first by descending 或者返回先按username
values and then by ascending date
values, such as:username
值降序,然后按date
值升序排序的结果的查询,例如:
db.events.find().sort( { username: -1, date: 1 } )
The following index can support both these sort operations:以下索引可以同时支持这两种排序操作:
db.events.createIndex( { "username" : 1, "date" : -1 } )
However, the above index cannot support sorting by ascending 但是,上述索引不支持先按username
values and then by ascending date
values, such as the following:username
值升序,然后按date
值升序排序,例如:
db.events.find().sort( { username: 1, date: 1 } )
For more information on sort order and compound indexes, see Use Indexes to Sort Query Results.有关排序顺序和复合索引的详细信息,请参阅使用索引对查询结果进行排序。
Prefixes前缀
Index prefixes are the beginning subsets of indexed fields. 索引前缀是索引字段的起始子集。For example, consider the following compound index:例如,考虑以下复合索引:
{ "item": 1, "location": 1, "stock": 1 }
The index has the following index prefixes:该索引具有以下索引前缀:
-
{ item: 1 }
-
{ item: 1, location: 1 }
For a compound index, MongoDB can use the index to support queries on the index prefixes. 对于复合索引,MongoDB可以使用该索引来支持对索引前缀的查询。As such, MongoDB can use the index for queries on the following fields:因此,MongoDB可以使用索引查询以下字段:
-
theitem
field,item
字段, -
theitem
field and thelocation
field,item
字段和location
字段, -
theitem
field and thelocation
field and thestock
field.location
字段和location
字段以及stock
字段。
MongoDB can also use the index to support a query on the MongoDB还可以使用索引来支持对item
and stock
fields, since the item
field corresponds to a prefix. item
和stock
字段的查询,因为item
字段对应于前缀。However, in this case the index would not be as efficient in supporting the query as it would be if the index were on only 然而,在这种情况下,索引在支持查询方面的效率不如仅针对item
and stock
. item
和stock
的索引。Index fields are parsed in order; if a query omits a particular index prefix, it is unable to make use of any index fields that follow that prefix.索引字段按顺序解析;如果查询省略了特定的索引前缀,则无法使用该前缀后面的任何索引字段。
Since a query on 由于对item
and stock
omits the location
index prefix, it cannot use the stock
index field which follows location
. item
和stock
的查询省略了location
索引前缀,因此不能使用location
后面的stock
索引字段。Only the 只有索引中的item
field in the index can support this query. item
字段才能支持此查询。See Create Indexes to Support Your Queries for more information.有关详细信息,请参阅创建索引以支持查询。
MongoDB cannot use the index to support queries that include the following fields since without the MongoDB不能使用索引来支持包含以下字段的查询,因为如果没有item
field, none of the listed fields correspond to a prefix index:item
字段,列出的字段都不会对应于前缀索引:
-
thelocation
field,location
字段, -
thestock
field, orstock
字段,或 -
thelocation
andstock
fields.location
和stock
字段。
If you have a collection that has both a compound index and an index on its prefix (e.g. 如果集合的前缀上同时有复合索引和索引(例如{ a: 1, b: 1 }
and { a: 1 }
), if neither index has a sparse or unique constraint, then you can remove the index on the prefix (e.g. { a: 1 }
). { a: 1, b: 1 }
和{ a: 1 }
),如果两个索引都没有稀疏或唯一约束,则可以删除前缀上的索引(例如{ a: 1 }
)。MongoDB will use the compound index in all of the situations that it would have used the prefix index.MongoDB将在所有使用前缀索引的情况下使用复合索引。
Index Intersection索引交叉点
MongoDB can use index intersection to fulfill queries. MongoDB可以使用索引交集来完成查询。The choice between creating compound indexes that support your queries or relying on index intersection depends on the specifics of your system. 创建支持查询的复合索引还是依赖索引交集取决于系统的具体情况。See Index Intersection and Compound Indexes for more details.有关详细信息,请参阅索引交集和复合索引。
Sparse Compound Indexes稀疏复合索引
Compound indexes can contain different types of sparse indexes. 复合索引可以包含不同类型的稀疏索引。The combination of index types determines how the compound index matches documents.索引类型的组合决定了复合索引与文档的匹配方式。
This table summarizes the behavior of a compound index that contains different types of sparse indexes:此表总结了包含不同类型稀疏索引的复合索引的行为:
geospatial fields. geospatial 字段的值时,才对其进行索引。 | |
text fields. text 字段匹配时,才对其进行索引。 |
Additional Considerations其他注意事项
During index builds, applications may encounter reduced performance or limited read/write access to the collection being indexed.在索引构建过程中,应用程序可能会遇到性能下降或对正在索引的集合的读/写访问受限的情况。
For more information on the index build process, see Index Builds on Populated Collections, especially the Index Builds in Replicated Environments section.有关索引生成过程的详细信息,请参阅填充集合上的索引生成,特别是复制环境中的索引生成部分。
Some drivers use 一些驱动程序使用NumberLong(1)
instead of 1
to specify the index order. NumberLong(1)
而不是1来指定索引顺序。The resulting indexes are the same.生成的索引是相同的。