createIndexes
定义
createIndexes
为集合构建一个或多个索引。
提示
在
mongosh
中,此命令也运行通过db.collection.createIndex()
和db.collection.createIndexes()
辅助方法运行。辅助方法对
mongosh
用户来说很方便,但它们返回的信息级别可能与数据库命令不同。如果不追求方便或需要额外的返回字段,请使用数据库命令。
兼容性
此命令可用于以下环境中托管的部署:
MongoDB Atlas:用于云中 MongoDB 部署的完全托管服务
注意
所有 MongoDB Atlas 集群都支持此命令。有关 Atlas 对所有命令的支持的信息,请参阅不支持的命令。
MongoDB Enterprise:基于订阅、自我管理的 MongoDB 版本
MongoDB Community:源代码可用、免费使用且可自行管理的 MongoDB 版本
语法
createIndexes
命令采用以下形式:
db.runCommand( { createIndexes: <collection>, indexes: [ { key: { <key-value_pair>, <key-value_pair>, ... }, name: <index_name>, <option1>, <option2>, ... }, { ... }, { ... } ], writeConcern: { <write concern> }, commitQuorum: <int|string>, comment: <any> } )
命令字段
createIndexes
命令采用以下字段:
字段 | 类型 | 说明 |
---|---|---|
| 字符串 | 要创建索引的集合。 |
| 阵列 | 指定要创建的索引。数组中的每个文档都指定一个单独的索引。 |
| 文档 | 可选。表达写关注的文档。省略以使用默认写关注。 |
| 整数或字符串 | 可选。承载数据的副本集成员的最小数量(即提交法定节点数),包括主节点,必须在主节点将 从 MongoDB v5.0 开始,当 为 时,您可以恢复一些 提交法定人数中的副本集节点必须将 支持以下值:
|
| any | 可选。用户提供的待附加到该命令的注释。设置后,该注释将与该命令的记录一起出现在以下位置:
注释可以是任何有效的 BSON 类型(字符串、整型、对象、数组等)。 |
indexes
数组中的每个文档都可以采用以下字段:
字段 | 类型 | 说明 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
| 文档 | 指定索引的字段。对于每个字段,指定一个键值对,其中键是要索引的字段的名称,值是索引方向或索引类型。如果指定方向,请指定 MongoDB 支持多种不同的索引类型,包括文本索引、地理空间索引和哈希索引。 有关更多信息,请参阅索引类型。 在版本 4.2 中进行了更改:MongoDB 4.2通配符索引支持用户查询自定义字段或collection中的大量字段的工作负载:
通配符索引键必须使用上面列出的语法之一。 例如,您不能指定复合索引键。 有关通配符索引的更完整文档(包括创建限制),请参阅通配符索引限制。
| ||||||||||
| 字符串 | 唯一地标识索引的名称。 | ||||||||||
| 布尔 | |||||||||||
| 文档 | |||||||||||
| 布尔 | |||||||||||
| 整型 | 可选。指定以秒为单位的生存时间 (TTL) 值,以便控制 MongoDB 在此集合中保留文档的时长。此选项仅会应用于 TTL 索引。请参阅通过设置 TTL 使集合中的数据过期以了解更多信息。 如果您使用 MongoDB 5.0 之前版本创建的 TTL 索引,或者要将 MongDB 5.0 创建的数据与之前版本同步,请参阅使用 NaN 配置索引,以避免错误配置问题。 TTL 索引 | ||||||||||
布尔 | 可选。一个标志,用于确定索引是否对查询规划器隐藏。选择查询计划时不会对隐藏索引进行评估。 默认值为 | |||||||||||
| 文档 | 可选。允许用户在创建索引时基于每个索引配置存储引擎。
在复制过程中,对创建索引时指定的存储引擎配置选项进行验证并记录到 oplog 中,以支持包含使用不同存储引擎的成员的副本集。 | ||||||||||
| 文档 | 可选。对于文本索引,指包含字段和权重对的文档。权重是一个介于 1 到 99,999 之间的整数,表示该字段相对于其他索引字段的得分重要性。您可以为部分或全部索引字段指定权重。请参阅为自管部署上的文本搜索结果分配权重来调整得分。默认值为 | ||||||||||
| 字符串 | 可选。对于文本索引,确定停止词列表的语言以及词干分析器和分词器的规则。欲了解更多信息和示例,请参阅自管理部署上的文本搜索语言和为自管理部署上的文本索引指定默认语言。默认值为 | ||||||||||
| 字符串 | 可选。 对于文本索引,为collection文档中包含文档覆盖语言的字段的名称。默认值为 | ||||||||||
| 整型 | 可选。 有关可用版本,请参阅版本。 | ||||||||||
| 整型 | 可选。 有关可用版本,请参阅版本。 | ||||||||||
| 整型 | |||||||||||
| 数字 | 可选。对于 2d 索引,这是经度和纬度值的包含下边界。默认值为 | ||||||||||
| 数字 | 可选。对于 2d 索引,这是经度和纬度值的包含上边界。默认值为 | ||||||||||
| 数字 | 对于geoHaystack索引,请指定对位置值进行分组的单位数量;即将彼此在指定单位数内的位置值分组在同一个存储桶中。 该值必须大于 0。 | ||||||||||
| 文档 | 可选。指定索引的排序规则。 排序规则允许用户为字符串比较指定特定于语言的规则,例如字母大小写和重音符号规则。 如果在集合级别指定排序规则:
排序规则选项的语法如下:
指定排序规则时, | ||||||||||
| 文档 | 可选。 允许用户使用
默认情况下,通配符索引会省略
除了显式包含 |
mongosh
提供方法 db.collection.createIndex()
和 db.collection.createIndexes()
作为 createIndexes
命令的封装器。
Considerations
MongoDB 不允许创建版本 0 索引。
索引名称
注意
在 MongoDB 4.2 中进行了更改
MongoDB 删除了最大127字节的索引名称长度限制。
从版本4.2开始,如果您使用一个名称创建索引,然后尝试使用其他名称再次创建相同索引,则createIndexes
命令以及mongosh
助手db.collection.createIndex()
和db.collection.createIndexes()
会报告错误。
{ "ok" : 0, "errmsg" : "Index with name: x_1 already exists with a different name", "code" : 85, "codeName" : "IndexOptionsConflict" }
在以前的版本中,MongoDB 不会再次创建索引,但会返回 ok
值为 1
的响应对象以及暗示未重新创建索引的注释。例如:
{ "numIndexesBefore" : 2, "numIndexesAfter" : 2, "note" : "all indexes already exist", "ok" : 1 }
副本集和分片集群
注意
需要 featureCompatibilityVersion 4.4+
副本集或分片集群中的每个 mongod
必须将 featureCompatibilityVersion 设置为至少 4.4
,才能跨副本集节点同时启动索引构建。
索引构建在副本集或分片集群上,并在所有数据承载副本集成员上同时构建。对于分片集群,索引构建仅会在包含当前被索引集合的数据的分片上进行。主节点需要最少数量的数据承载 voting
节点(即提交法定节点数),包括其自身,这些节点必须在将索引标记为可供使用之前完成构建。 有关详细信息,请参阅复制环境中的索引构建。
要使用非默认提交法定人数启动索引构建,请指定 commitQuorum。
使用 setIndexCommitQuorum
命令修改正在进行的索引构建的提交法定节点数。
为了最大限度地减少构建索引对副本集和分片集群的影响,请使用滚动索引构建过程,如在副本集上构建滚动索引中所述。
排序规则和索引类型
以下索引只支持简单的二进制比较,不支持排序规则:
文本索引,
2d索引,以及
geoHaystack索引。
提示
要在具有非简单排序规则的集合上创建text
、 2d
或geoHaystack
索引,您必须在创建索引时显式指定{collation: {locale: "simple"} }
。
Stable API
使用 Stable API V1 时:
您不能在
indexes
数组中指定以下任何字段:background
bucketSize
sparse
storageEngine
无法创建 geoHaystack 或文本索引。
在 严格模式 , 查询规划 器会忽略上述不支持的索引类型。示例,尝试将
sparse
索引与cursor.hint()
一起使用将导致以下BadValue
错误:planner returned error :: caused by :: hint provided does not correspond to an existing index
行为
并发
版本 4.2 中进行了更改。
对于 featureCompatibilityVersion "4.2"
,createIndexes
使用优化的构建进程,该进程在索引构建开始和结束时获取并保持对指定集合的独占锁。对集合的所有后续操作都必须等到 createIndexes
释放独占锁后进行。createIndexes
支持在索引构建的大部分时间交叉进行读写操作。
对于 featureCompatibilityVersion "4.0"
,createIndexes
会使用 4.2 之前的索引构建流程,默认情况下会获得在整个构建流程中持续应用于父数据库的独占锁。4.2 之前的构建流程会阻塞对数据库以及其所有集合的所有操作,直到该操作完成。background
索引不会采用独占锁。
有关 createIndexes
的锁定行为的更多信息,请参阅在填充集合上构建索引。
内存使用限制
createIndexes
支持在集合上建立一个或多个索引。createIndexes
使用磁盘上的内存和临时文件的组合来完成索引构建。createIndexes
的内存使用量的默认限制为 200 MB,在使用单个 createIndexes
命令生成的所有索引之间共享。达到内存限制后,createIndexes
将使用 --dbpath
目录中名为 _tmp
的子目录中的临时磁盘文件来完成构建。
您可以通过设置 maxIndexBuildMemoryUsageMegabytes
服务器参数来覆盖内存限制。设置更高的内存限制可能会加快完成索引构建过程。但是,相对于系统上未使用的 RAM 而言,将此限制设置得太高可能会导致内存耗尽和服务器关闭。
索引选项
Non-Hidden Option
更改索引选项
可以更新现有索引的排序规则选项。要更改其他索引选项,请先通过 db.collection.dropIndex()
删除现有索引,然后使用新选项运行 createIndexes
。
排序规则选项
您可以使用不同的排序规则对同一键创建多个索引。 要创建具有相同键模式但不同排序规则的索引,您必须提供唯一索引名称。
如果在集合级别指定排序规则:
如果创建索引时未指定排序规则,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 参数设置了什么值。
隐藏选项
注意
要隐藏索引,必须将 featureCompatibilityVersion 设置为 4.4
或更高版本。但是,一旦隐藏,即使在 MongoDB 4.4 二进制文件上将 featureCompatibilityVersion 设置为 4.2
,索引仍会保持隐藏状态。
要更改现有索引的 hidden
选项,您可以使用以下 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)
4.2 版本中的新增功能。
默认情况下,通配符索引会省略
_id
字段。要将_id
字段包含在通配符索引中,必须将其显式包含在wildcardProjection
文档中:{ "wildcardProjection" : { "_id" : 1, "<field>" : 0|1 } } 除了显式包含
_id
字段之外,您不能在wildcardProjection
文档中合并包含和排除声明。mongod
featureCompatibilityVersion必须为4.2
才能创建通配符索引。 有关设置 FCV 的说明,请参阅在 MongoDB 6.0 部署上设置特征兼容性版本。通配符索引不支持以下索引类型或属性:
有关通配符索引限制的完整文档,请参阅通配符索引限制。
事务
如果事务不是跨分片写事务,则可以在分布式事务中创建集合和索引。
要在事务中使用 createIndexes
,该事务必须使用读关注 "local"
。如果指定 "local"
以外的读关注级别,则该事务将失败。
例子
以下命令会在 products
数据库的 inventory
集合上构建两个索引:
db.getSiblingDB("products").runCommand( { createIndexes: "inventory", indexes: [ { key: { item: 1, manufacturer: 1, model: 1 }, name: "item_manufacturer_model", unique: true }, { key: { item: 1, supplier: 1, model: 1 }, name: "item_supplier_model", unique: true } ], writeConcern: { w: "majority" } } )
在索引成功完成构建时,MongoDB 返回一个结果文档,其中包含 "ok" : 1
状态。
创建通配符索引
版本 4.2 中的新增功能: mongod
featureCompatibilityVersion必须为4.2
才能创建通配符索引。 有关设置 FCV 的说明,请参阅在 MongoDB 6.0 部署上设置特征兼容性版本。
有关“通配符索引”的完整文档,请参阅“通配符索引”。
下面列出了创建通配符索引的示例:
对单个字段路径(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.runCommand( { createIndexes: "products_catalog", indexes: [ { key: { "product_attributes.$**" : 1 }, name: "wildcardIndex" } ] } )
通过此通配符索引,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.runCommand( { createIndexes: "products_catalog", indexes: [ { key: { "$**" : 1 }, name: "wildcardIndex" } ] } )
通过此通配符索引,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.runCommand( { createIndexes: "products_catalog", indexes: [ { key: { "$**" : 1 }, "wildcardProjection" : { "product_attributes.elements" : 1, "product_attributes.resistance" : 1 }, name: "wildcardIndex" } ] } )
虽然键模式 "$**"
涵盖了文档中的所有字段,但 wildcardProjection
字段将索引限制为只有所包含的字段及其嵌套字段。
如果字段是嵌套文档或数组,则通配符索引将递归到文档/数组中并对文档/数组中的所有标量字段构建索引。
创建的索引可支持对 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.runCommand( { createIndexes: "products_catalog", indexes: [ { key: { "$**" : 1 }, "wildcardProjection" : { "product_attributes.elements" : 0, "product_attributes.resistance" : 0 }, name: "wildcardIndex" } ] } )
键模式"$**"
涵盖文档中的所有字段,而wildcardProjection
字段则从索引中排除指定字段。
如果字段是嵌套文档或数组,则通配符索引将递归到文档/数组中并对文档/数组中的所有标量字段构建索引。
创建的索引可以支持对任何标量字段的查询,但 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 选项,以设置承载数据的投票成员(即提交法定人数)(包括主节点)的最小数量,主节点必须在主节点将索引标记为就绪之前完成索引构建。默认提交法定人数为votingMembers
,或所有承载数据的副本集节点。
以下操作创建了提交法定人数为 "majority"
的索引,或简单多数的数据承载投票成员:
db.getSiblingDB("examples").runCommand( { createIndexes: "invoices", indexes: [ { key: { "invoices" : 1 }, "name" : "invoiceIndex" } ], "commitQuorum" : "majority" } )
仅在简单多数承载数据的投票成员“投票”提交索引构建后,主节点才会将索引构建标记为准备就绪。有关索引构建和投票过程的更多信息,请参阅复制环境中的索引构建。
输出
createIndexes
命令会返回一个文档,表示操作成功。该文档包含以下部分(但并非全部)字段,具体取决于结果: