db.collection.createIndexes()
在此页面上
带驱动程序的 MongoDB
本页面提供 mongosh
方法的相关信息。要查看 MongoDB 驱动程序中的等效方法,请参阅编程语言的相应页面:
定义
db.collection.createIndexes( [ keyPatterns ], options, commitQuorum )
在集合上创建一个或多个索引。
为了最大限度地减少构建索引对副本集和分片集群的影响,请使用滚动索引构建过程,如 在副本集上构建滚动索引中所述。
db.collection.createIndexes()
使用以下参数:Parameter类型说明keyPatterns
文档
options
文档
整数或字符串
可选。承载数据的投票副本集成员的最小数量(即提交法定节点数),包括主节点,必须在主节点将
indexes
标记为就绪之前报告索引构建成功。“投票”成员是members[n].votes
大于0
的任何副本集成员。支持以下值:
"votingMembers"
- 所有承载数据的有投票权副本集成员(默认)。"majority"
- 数据承载投票副本集成员的简单多数制。<int>
- 特定数量的承载数据的副本集投票节点。0
- 禁用法定人数投票行为。成员同时开始索引构建,但在完成索引构建之前不投票或等待法定人数。如果您使用0
的提交法定人数启动索引构建,则以后无法使用setIndexCommitQuorum
修改提交法定人数。副本集标记名称。
兼容性
此方法可用于以下环境中托管的部署:
MongoDB Atlas:用于云中 MongoDB 部署的完全托管服务
注意
所有 MongoDB Atlas 集群都支持此命令。有关 Atlas 对所有命令的支持的信息,请参阅不支持的命令。
MongoDB Enterprise:基于订阅、自我管理的 MongoDB 版本
MongoDB Community:源代码可用、免费使用且可自行管理的 MongoDB 版本
Stable API
使用 Stable API V1 时:
您不能在
options
文档中指定以下任何字段:background
bucketSize
sparse
storageEngine
无法创建 geoHaystack 或文本索引。
在 严格模式 , 查询规划 器会忽略上述不支持的索引类型。示例,尝试将
sparse
索引与cursor.hint()
一起使用将导致以下BadValue
错误:planner returned error :: caused by :: hint provided does not correspond to an existing index
选项
options
文档包含一组控制索引创建的选项。不同索引类型可以具备特定的附加选项。
同一文档中可指定多个索引选项。但是,如果指定多个选项文档,db.collection.createIndexes()
操作将失败。
请考虑下面的 db.collection.createIndexes()
操作:
db.collection.createIndexes( [ { "a": 1 }, { "b": 1 } ], { unique: true, sparse: true, expireAfterSeconds: 3600 } )
如果选项规范被拆分为多个文档(如下所示: { unique: true }, { sparse: true, expireAfterSeconds: 3600 }
),索引创建操作将失败。
重要
如果将选项指定为 db.collection.createIndexes()
,则这些选项适用于所有指定的索引。例如,如果指定排序规则选项,则创建的所有索引都将包含该排序规则。
db.collection.createIndexes()
会返回错误信息(如果您尝试使用不兼容的选项或过多参数创建索引)。请参阅选项说明以获取更多信息。
所有索引类型的选项
除非另有说明,否则以下选项可用于所有索引类型:
Parameter | 类型 | 说明 | |
---|---|---|---|
| 布尔 | ||
| 字符串 | 可选。索引名称。如果未指定,MongoDB 将通过连接索引字段的名称和排序顺序来生成索引名称。
| |
| 文档 | ||
| 布尔 | ||
| 整型 | 可选。指定以秒为单位的生存时间 (TTL) 值,以便控制 MongoDB 在此集合中保留文档的时长。此选项仅会应用于 TTL 索引。请参阅通过设置 TTL 使集合中的数据过期以了解更多信息。 如果您使用 MongoDB 5.0 之前版本创建的 TTL 索引,或者要将 MongDB 5.0 创建的数据与之前版本同步,请参阅使用 NaN 配置索引,以避免错误配置问题。 TTL 索引 | |
布尔 | 可选。一个标志,用于确定是否从查询规划器中隐藏索引。隐藏索引不会作为查询计划选择的一部分进行评估。 默认值为 | ||
| 文档 | 可选。允许用户为创建的索引配置存储引擎。
在复制过程中,对创建索引时指定的存储引擎配置选项进行验证并记录到 oplog 中,以支持包含使用不同存储引擎的成员的副本集。 |
排序规则选项
Parameter | 类型 | 说明 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
| 文档 | 可选。指定索引的排序规则。 排序规则允许用户为字符串比较指定特定于语言的规则,例如字母大小写和重音符号规则。 如果在集合级别指定排序规则:
排序规则选项的语法如下:
指定排序规则时, |
以下索引只支持简单的二进制比较,不支持排序规则:
提示
要在具有非简单排序规则的集合上创建 text
或 2d
索引,您必须在创建索引时显式指定 {collation:
{locale: "simple"} }
。
排序规则和索引使用
如果在集合级别指定排序规则:
如果创建索引时未指定排序规则,MongoDB 将使用集合的默认排序规则创建索引。
如果您在创建索引时指定了排序规则,MongoDB 将使用指定的排序规则创建索引。
提示
通过指定排序规则 strength
为 1
或 2
,您可以创建不区分大小写的索引。排序规则 strength
为 1
的索引既不区分变音符号,也不区分大小写。
您可以使用不同的排序规则对同一键创建多个索引。 要创建具有相同键模式但不同排序规则的索引,您必须提供唯一索引名称。
要使用索引进行字符串比较,操作还必须指定相同的排序规则。换言之,如果一个操作对索引字段进行字符串比较,但又设定了与索引字段不同的排序规则,那么这个设有排序规则的索引将无法支持该操作。
警告
由于配置了排序规则的索引是通过 ICU 排序规则键来实现排序,因此,相比未配置排序规则的索引的索引键,有排序规则感知的索引键可能会更大。
例如,集合 myColl
在字符串字段 category
上具有一个索引,排序规则语言环境为 "fr"
。
db.myColl.createIndex( { category: 1 }, { collation: { locale: "fr" } } )
以下查询操作指定了与索引相同的排序规则,因此可以使用索引:
db.myColl.find( { category: "cafe" } ).collation( { locale: "fr" } )
而以下查询操作默认使用“简易的”二进制排序器,因此无法使用索引:
db.myColl.find( { category: "cafe" } )
如果一个复合索引的前缀键不是字符串、数组和嵌入式文档,在这种情况下,即使查询操作指定了一个与索引不同的排序规则,它仍然可以利用该复合索引来支持对其前缀健的比较。
例如,集合 myColl
在数值字段 score
和 price
以及字符串字段 category
上有一个复合索引;该索引使用排序规则语言环境 "fr"
创建,用于进行字符串比较:
db.myColl.createIndex( { score: 1, price: 1, category: 1 }, { collation: { locale: "fr" } } )
以下操作使用 "simple"
二进制排序规则进行字符串比较,它们可以使用索引:
db.myColl.find( { score: 5 } ).sort( { price: 1 } ) db.myColl.find( { score: 5, price: { $gt: NumberDecimal( "10" ) } } ).sort( { price: 1 } )
以下操作使用 "simple"
二进制排序规则对索引的 category
字段进行字符串比较,它们可以使用索引仅完成查询的 score: 5
部分:
db.myColl.find( { score: 5, category: "cafe" } )
重要
与文档键(包括嵌入式文档键)的匹配使用简单的二进制比较。这意味着类似“foo.bár”的键的查询不会匹配“foo.bar”键,无论您为 strength 参数设置了什么值。
text
索引的选项
以下选项仅适用于文本索引:
Parameter | 类型 | 说明 |
---|---|---|
| 文档 | 可选。对于文本索引,指包含字段和权重对的文档。权重是一个介于 1 到 99,999 之间的整数,表示该字段相对于其他索引字段的得分重要性。您可以为部分或全部索引字段指定权重。请参阅为自管部署上的文本搜索结果分配权重来调整得分。默认值为 从 MongoDB 5.0 开始,只有文本索引才允许使用 weights 选项。 |
| 字符串 | 可选。对于文本索引,确定停止词列表的语言以及词干分析器和分词器的规则。欲了解更多信息和示例,请参阅自管理部署上的文本搜索语言和为自管理部署上的文本索引指定默认语言。默认值为 |
| 字符串 | 可选。对于文本索引,则为集合的文档中包含文档替代语言的字段的名称。默认值是 |
| 整型 | 可选。 有关可用版本,请参阅自管理部署上的文本索引版本。 |
2dsphere
索引的选项
以下选项仅适用于 2dsphere 索引:
Parameter | 类型 | 说明 |
---|---|---|
| 整型 | 可选。 有关可用版本,请参阅 2dsphere 索引。 |
2d
索引的选项
以下选项仅适用于 2d
索引:
Parameter | 类型 | 说明 |
---|---|---|
| 整型 | 可选。对于
|
| 数字 | 可选。 对于 |
| 数字 | 可选。对于 |
wildcard
索引的选项
以下选项仅适用于通配符索引:
Parameter | 类型 | 说明 | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 文档 | 可选。允许用户在通配符索引中包含或排除特定字段路径。 仅当您在所有文档字段上创建通配符索引时,此选项才有效。在特定字段路径及其子字段上创建通配符索引时,不能指定
但是,您无法定义在通配符字段中包含相同字段以及常规(非通配符)字段的索引。要正确定义索引,请使用
默认情况下,通配符索引会省略
|
行为
重新创建现有索引
如果为已存在的一个或多个索引调用 db.collection.createIndexes()
,则 MongoDB 不会重新创建现有的一个或多个索引。
索引选项
非排序和非隐藏选项
除排序规则选项外,如果使用一组索引选项创建一个索引,然后尝试使用其他索引选项重新创建同一索引,MongoDB 不会更改选项,也不会重新创建索引。
可以在不删除和重新创建索引的情况下更改隐藏选项。请参阅隐藏选项。
要更改其他索引选项,请先使用 db.collection.dropIndex()
删除现有索引,然后使用新选项运行 db.collection.createIndexes()
。
排序规则选项
您可以使用不同的排序规则对同一键创建多个索引。 要创建具有相同键模式但不同排序规则的索引,您必须提供唯一索引名称。
隐藏选项
要隐藏或取消隐藏现有索引,可使用以下 mongosh
方法:
例如,
要将索引的
hidden
选项更改为true
,请使用db.collection.hideIndex()
方法:db.restaurants.hideIndex( { borough: 1, ratings: 1 } ); 要将索引的
hidden
选项更改为false
,请使用db.collection.unhideIndex()
方法:db.restaurants.unhideIndex( { borough: 1, city: 1 } );
通配符索引 (Wildcard Indexes)
默认情况下,通配符索引会省略
_id
字段。要将_id
字段包含在通配符索引中,必须将其显式包含在wildcardProjection
文档中:{ "wildcardProjection" : { "_id" : 1, "<field>" : 0|1 } } wildcardProjection
文档中的所有语句必须是包含语句或排除语句中的一种。您还可以在排除语句中包含_id
字段。这是该规则的唯一例外。不支持通配符索引:
通配符索引是稀疏(Sparse)索引。当索引字段不存在时,它们不支持查询。如果通配符字段的值为
null
,则通配符索引将对文档进行索引。从 MongoDB 7.0 开始,通配符索引支持升序 (
1
) 和降序 (-1
) 排序顺序。早期版本仅支持升序。
要了解详情,请参阅:
事务
如果事务不是跨分片写事务,则可以在分布式事务中创建集合和索引。
要在事务中使用 db.collection.createIndexes()
,该事务必须使用读关注 "local"
。如果指定 "local"
以外的读关注级别,则该事务将失败。
索引构建
在版本 7.1 中进行了更改。
从 MongoDB 7.1 开始,索引构建得到了改进,报告速度更快,韧性更强。您还可以使用新的indexBuildMinAvailableDiskSpaceMB
参数设置索引构建所需的最小可用磁盘空间,如果磁盘空间太低,该参数会停止索引构建。
下表比较了从 MongoDB 7.1 开始与早期版本的索引构建行为。
从 MongoDB 7.1 开始的行为 | 早期 MongoDB 版本中的行为 |
---|---|
在collection扫描阶段发现的索引错误(重复键错误除外)会立即返回,然后停止索引构建。早期的 MongoDB 版本会在提交阶段返回错误,该阶段发生在索引构建接近结束时。 MongoDB 7.1 可帮助您快速诊断索引错误。 例如,如果发现不兼容的索引值格式,则会立即向您返回错误信息。 | 与 MongoDB 7.1 相比,索引构建错误可能需要很长时间才能返回,因为错误是在提交阶段的索引构建接近结束时返回的。 |
索引构建错误可能会导致从节点崩溃。 | |
改进了索引构建的磁盘空间管理。 如果可用磁盘空间低于 | 如果可用磁盘空间不足,则索引构建不会停止。 |
例子
在不使用选项的情况下创建索引
考虑包含类似于以下内容的文档的restaurants
集合:
{ location: { type: "Point", coordinates: [-73.856077, 40.848447] }, name: "Morris Park Bake Shop", cuisine: "Cafe", borough: "Bronx", }
以下示例在 restaurants
集合上创建两个索引:在 borough
字段上创建升序索引,在 location
字段上创建 2dsphere 索引。
db.restaurants.createIndexes([{"borough": 1}, {"location": "2dsphere"}])
使用指定排序规则创建索引
以下示例对 products
集合创建两个索引:对 manufacturer
字段创建升序索引,对 category
字段创建升序索引。两个索引都使用排序规则,用于指定区域设置 fr
和比较强度 2
:
db.products.createIndexes( [ { "manufacturer": 1}, { "category": 1 } ], { collation: { locale: "fr", strength: 2 } })
对于使用相同排序规则的索引键的查询或排序操作,MongoDB 可以使用索引。有关详细信息,请参阅排序规则和索引使用。
创建通配符索引
有关“通配符索引”的完整文档,请参阅“通配符索引”。
下面列出了创建通配符索引的示例:
对单个字段路径(Field Path)创建通配符索引
以某一 products_catalog
集合为例,其中的文档可能包含 product_attributes
字段。product_attributes
字段可包含任意嵌套字段,其中包括嵌入式文档文档和数组:
db.products_catalog.insertMany( [ { _id : ObjectId("5c1d358bf383fbee028aea0b"), product_name: "Blaster Gauntlet", product_attributes: { price: { cost: 299.99, currency: "USD" } } }, { _id: ObjectId("5c1d358bf383fbee028aea0c"), product_name: "Super Suit", product_attributes: { superFlight: true, resistance: [ "Bludgeoning", "Piercing", "Slashing" ] } } ] )
以下操作在 product_attributes
字段上创建一个通配符索引:
use inventory db.products_catalog.createIndexes( [ { "product_attributes.$**" : 1 } ] )
通过此通配符索引,MongoDB 可以对 product_attributes
的所有标量值建立索引。如果字段是嵌套文档或数组,则通配符索引将递归到文档/数组中,并为文档/数组中的所有标量字段建立索引。
通配符索引可以支持对 product_attributes
或其嵌套字段之一进行任意单字段查询:
db.products_catalog.find( { "product_attributes.superFlight" : true } ) db.products_catalog.find( { "product_attributes.maxSpeed" : { $gt : 20 } } ) db.products_catalog.find( { "product_attributes.elements" : { $eq: "water" } } )
注意
特定于路径的通配符索引语法与 wildcardProjection
选项不兼容。有关更多信息,请参阅参数文档。
对所有字段路径创建通配符索引
以某一 products_catalog
集合为例,其中的文档可能包含 product_attributes
字段。product_attributes
字段可包含任意嵌套字段,其中包括嵌入式文档文档和数组:
db.products_catalog.insertMany( [ { _id : ObjectId("5c1d358bf383fbee028aea0b"), product_name: "Blaster Gauntlet", product_attributes: { price: { cost: 299.99, currency: "USD" } } }, { _id: ObjectId("5c1d358bf383fbee028aea0c"), product_name: "Super Suit", product_attributes: { superFlight: true, resistance: [ "Bludgeoning", "Piercing", "Slashing" ] } } ] )
以下操作对所有标量字段(不包括 _id
字段)创建通配符索引:
use inventory db.products_catalog.createIndexes( [ { "$**" : 1 } ] )
通过此通配符索引,MongoDB 可为集合中每个文档的所有标量字段建立索引。如果给定字段是嵌套文档或数组,则通配符索引将递归到文档/数组中并对文档/数组中的所有标量字段构建索引。
创建的索引可以支持对集合中文档内任意字段的查询:
db.products_catalog.find( { "product_price" : { $lt : 25 } } ) db.products_catalog.find( { "product_attributes.elements" : { $eq: "water" } } )
注意
默认情况下,通配符索引会省略 _id
字段。要将 _id
字段包含在通配符索引中,则必须将其明确包含在wildcardProjection
文档中。查看参数文档以获取更多信息。
在多个特定字段路径上创建通配符索引
以某一 products_catalog
集合为例,其中的文档可能包含 product_attributes
字段。product_attributes
字段可包含任意嵌套字段,其中包括嵌入式文档文档和数组:
db.products_catalog.insertMany( [ { _id : ObjectId("5c1d358bf383fbee028aea0b"), product_name: "Blaster Gauntlet", product_attributes: { price: { cost: 299.99, currency: "USD" } } }, { _id: ObjectId("5c1d358bf383fbee028aea0c"), product_name: "Super Suit", product_attributes: { superFlight: true, resistance: [ "Bludgeoning", "Piercing", "Slashing" ] } } ] )
以下操作创建通配符索引并使用wildcardProjection
选项,以仅在索引中包含product_attributes.elements
和product_attributes.resistance
字段的标量值。
use inventory db.products_catalog.createIndexes( [ { "$**" : 1 } ], { "wildcardProjection" : { "product_attributes.elements" : 1, "product_attributes.resistance" : 1 } } )
模式 "$**"
包括文档中的所有字段。使用 wildcardProjection
字段将索引限制为指定字段。
有关 wildcardProjection
的完整文档,请参阅 wildcard
索引的选项。
如果字段是嵌套文档或数组,则通配符索引将递归到文档/数组中并对文档/数组中的所有标量字段构建索引。
通配符索引支持对 wildcardProjection
中的任何标量字段进行查询:
db.products_catalog.find( { "product_attributes.elements" : { $eq: "Water" } } ) db.products_catalog.find( { "product_attributes.resistance" : "Bludgeoning" } )
注意
通配符索引不支持在 wildcardProjection
文档中混用包含和排除语句,除非显示包含 _id
字段时。有关 wildcardProjection
的更多信息,请参阅参数文档。
在通配符索引覆盖中省略特定字段
以某一 products_catalog
集合为例,其中的文档可能包含 product_attributes
字段。product_attributes
字段可包含任意嵌套字段,其中包括嵌入式文档文档和数组:
db.products_catalog.insertMany( [ { _id : ObjectId("5c1d358bf383fbee028aea0b"), product_name: "Blaster Gauntlet", product_attributes: { price: { cost: 299.99, currency: "USD" } } }, { _id: ObjectId("5c1d358bf383fbee028aea0c"), product_name: "Super Suit", product_attributes: { superFlight: true, resistance: [ "Bludgeoning", "Piercing", "Slashing" ] } } ] )
此示例使用通配符索引和 wildcardProjection
文档来为集合中每个文档的标量字段构建索引。通配符索引会排除 product_attributes.elements
和 product_attributes.resistance
字段:
use inventory db.products_catalog.createIndexes( [ { "$**" : 1 } ], { "wildcardProjection" : { "product_attributes.elements" : 0, "product_attributes.resistance" : 0 } } )
通配符模式 "$**"
包括文档中的所有字段。但是,wildcardProjection
字段会将指定字段排除在索引之外。
有关 wildcardProjection
的完整文档,请参阅 wildcard
索引的选项。
如果字段是嵌套文档或数组,则通配符索引将递归到文档/数组中并对文档/数组中的所有标量字段构建索引。
该索引可支持对任意标量字段的查询,但不含 wildcardProjection
所排除的字段:
db.products_catalog.find( { "product_attributes.maxSpeed" : { $gt: 25 } } ) db.products_catalog.find( { "product_attributes.superStrength" : true } )
注意
通配符索引不支持在 wildcardProjection
文档中混用包含和排除语句,除非显示包含 _id
字段时。有关 wildcardProjection
的更多信息,请参阅参数文档。
使用提交法定人数创建索引
注意
需要 featureCompatibilityVersion 4.4+
副本集或分片集群中的每个 mongod
必须将 featureCompatibilityVersion 设置为至少 4.4
,才能跨副本集节点同时启动索引构建。
索引构建在副本集或分片集群上,并在所有数据承载副本集成员上同时构建。对于分片集群,索引构建仅会在包含当前被索引集合的数据的分片上进行。主节点需要最少数量的数据承载 voting
节点(即提交法定节点数),包括其自身,这些节点必须在将索引标记为可供使用之前完成构建。 有关详细信息,请参阅复制环境中的索引构建。
要设置提交法定人数,请使用 createIndexes()
来指定 commitQuorum
值。
commitQuorum
指定在主成员执行提交之前必须准备好多少个承载数据的投票成员或哪些投票成员(包括主节点)来提交索引构建。默认提交法定人数为 votingMembers
,这意味着是所有承载数据的成员。
以下操作将创建提交法定人数为 "majority"
的索引:
db.getSiblingDB("examples").invoices.createIndexes( { "invoices" : 1 }, { }, "majority" )
仅在简单多数承载数据的投票成员“投票”提交索引构建后,主节点才会将索引构建标记为准备就绪。有关索引构建和投票过程的更多信息,请参阅复制环境中的索引构建。
创建多个索引
创建cakeSales
集合,其中包含加利福尼亚州 ( CA
) 和华盛顿州 ( WA
) 的蛋糕销售情况:
db.cakeSales.insertMany( [ { _id: 0, type: "chocolate", orderDate: new Date("2020-05-18T14:10:30Z"), state: "CA", price: 13, quantity: 120 }, { _id: 1, type: "chocolate", orderDate: new Date("2021-03-20T11:30:05Z"), state: "WA", price: 14, quantity: 140 }, { _id: 2, type: "vanilla", orderDate: new Date("2021-01-11T06:31:15Z"), state: "CA", price: 12, quantity: 145 }, { _id: 3, type: "vanilla", orderDate: new Date("2020-02-08T13:13:23Z"), state: "WA", price: 13, quantity: 104 }, { _id: 4, type: "strawberry", orderDate: new Date("2019-05-18T16:09:01Z"), state: "CA", price: 41, quantity: 162 }, { _id: 5, type: "strawberry", orderDate: new Date("2019-01-08T06:12:03Z"), state: "WA", price: 43, quantity: 134 } ] )
以下示例将对 cakeSales
集合创建多个索引:
db.cakeSales.createIndexes( [ { "type": 1 }, { "orderDate": 1 }, { "state": 1 }, { "orderDate": 1, "state": -1 } ] )
前三个索引位于单个字段上,并按升序排列 (1
)。
最后一个索引位于 orderDate
上,并按升序排列 (1
);位于 state
上,并按降序排列 (-1
)。
更多信息
有关索引的其他信息,请参阅:
本手册的索引部分提供了 MongoDB 中有关索引和索引创建的完整文档。
db.collection.getIndexes()
查看集合现有索引的规范。有关创建
text
索引的详细信息,请参阅自管理部署中的文本索引。用于地理空间查询的地理空间索引。
TTL 索引以了解数据过期。