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
命令采用以下字段:
字段 | 类型 | 说明 |
---|---|---|
createIndexes | 字符串 | 要创建索引的集合。 |
indexes | 阵列 | 指定要创建的索引。数组中的每个文档都指定一个单独的索引。 |
writeConcern | 文档 | 可选。表达写关注的文档。省略以使用默认写关注。 |
commitQuorum | 整数或字符串 | 可选。承载数据的副本集成员的最小数量(即提交法定节点数),包括主节点,必须在主节点将 从 MongoDB v5.0 开始,当 为 时,您可以恢复一些 提交法定人数中的副本集节点必须将 支持以下值:
|
comment | any | 可选。用户提供的待附加到该命令的注释。设置后,该注释将与该命令的记录一起出现在以下位置:
注释可以是任何有效的 BSON 类型(字符串、整型、对象、数组等)。 |
indexes
数组中的每个文档都可以采用以下字段:
字段 | 类型 | 说明 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
key | 文档 | 指定索引的字段。对于每个字段,指定一个键值对,其中键是要索引的字段的名称,值是索引方向或索引类型。如果指定方向,请指定 MongoDB 支持多种不同的索引类型,包括文本索引、地理空间索引和哈希索引。 有关更多信息,请参阅索引类型。 在版本 4.2 中进行了更改:MongoDB 4.2通配符索引支持用户查询自定义字段或collection中的大量字段的工作负载:
通配符索引键必须使用上面列出的语法之一。 例如,您不能指定复合索引键。 有关通配符索引的更完整文档(包括创建限制),请参阅通配符索引限制。
有关创建通配符索引的示例,请参阅创建通配符索引。 | ||||||||||
name | 字符串 | 唯一地标识索引的名称。 | ||||||||||
unique | 布尔 | |||||||||||
partialFilterExpression | 文档 | |||||||||||
sparse | 布尔 | |||||||||||
expireAfterSeconds | 整型 | 可选。指定以秒为单位的生存时间 (TTL) 值,以便控制 MongoDB 在此集合中保留文档的时长。此选项仅会应用于 TTL 索引。请参阅通过设置 TTL 使集合中的数据过期以了解更多信息。 如果您使用 MongoDB 5.0 之前版本创建的 TTL 索引,或者要将 MongDB 5.0 创建的数据与之前版本同步,请参阅使用 NaN 配置索引,以避免错误配置问题。 TTL 索引 | ||||||||||
布尔 | 可选。一个标志,用于确定索引是否对查询规划器隐藏。选择查询计划时不会对隐藏索引进行评估。 默认值为 | |||||||||||
storageEngine | 文档 | 可选。允许用户在创建索引时基于每个索引配置存储引擎。
在复制过程中,对创建索引时指定的存储引擎配置选项进行验证并记录到 oplog 中,以支持包含使用不同存储引擎的成员的副本集。 | ||||||||||
weights | 文档 | 可选。对于文本索引,指包含字段和权重对的文档。权重是一个介于 1 到 99,999 之间的整数,表示该字段相对于其他索引字段的得分重要性。您可以为部分或全部索引字段指定权重。请参阅为自管部署上的文本搜索结果分配权重来调整得分。默认值为 1 。 | ||||||||||
default_language | 字符串 | |||||||||||
language_override | 字符串 | |||||||||||
textIndexVersion | 整型 | 可选。 有关可用版本,请参阅版本。 | ||||||||||
2dsphereIndexVersion | 整型 | 可选。 有关可用版本,请参阅版本。 | ||||||||||
bits | 整型 | |||||||||||
min | 数字 | 可选。对于 2d 索引,这是经度和纬度值的包含下边界。默认值为 -180.0 。 | ||||||||||
max | 数字 | 可选。对于 2d 索引,这是经度和纬度值的包含上边界。默认值为 180.0 。 | ||||||||||
bucketSize | 数字 | 对于geoHaystack索引,请指定对位置值进行分组的单位数量;即将彼此在指定单位数内的位置值分组在同一个存储桶中。 该值必须大于 0。 | ||||||||||
collation | 文档 | 可选。指定索引的排序规则。 排序规则允许用户为字符串比较指定特定于语言的规则,例如字母大小写和重音符号规则。 如果在集合级别指定排序规则:
排序规则选项的语法如下:
指定排序规则时, | ||||||||||
wildcardProjection | 文档 | 可选。 允许用户使用
默认情况下,通配符索引会省略
除了显式包含 |
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
命令会返回一个文档,表示操作成功。该文档包含以下部分(但并非全部)字段,具体取决于结果: