db.collection.createIndex()
本页
MongoDB与驱动程序
此页文档了一个mongosh方法。要查看特定编程语言的等效方法,请参阅相应页面
定义
db.collection.createIndex(keys, options, commitQuorum)在集合上创建索引。
为了最小化在副本集和分片集群上构建索引的影响,请使用滚动索引构建过程,如以下页面所述:副本集上的滚动索引构建.
兼容性
此方法在以下环境中托管的应用程序中可用
MongoDB Atlas:MongoDB在云中的托管服务
注意
此命令支持所有MongoDB Atlas集群。有关Atlas对所有命令的支持信息,请参阅不支持命令。
MongoDB Enterprise:基于订阅的自托管MongoDB版本
MongoDB Community:MongoDB的开源版本,免费使用,可自行管理
语法
createIndex() 方法具有以下形式
db.collection.createIndex( <keys>, <options>, <commitQuorum>)
createIndex() 方法接受以下参数
参数 | 类型 | 描述 |
|---|---|---|
keys | 文档 | |
options | 文档 | 可选。一个文档,包含一组选项,用于控制索引的创建。有关详细信息,请参阅选项。 |
整数或字符串 | 可选。必须在主节点将索引标记为就绪之前,报告成功的 索引构建 的数据承载投票副本集成员(即提交仲裁)的最小数量,包括主节点。一个“投票”成员是任何其 支持以下值
|
选项
options 文档包含一组选项,用于控制索引的创建。不同类型的索引可以具有特定于该类型的附加选项。
可以在同一文档中指定多个索引选项。然而,如果您指定了多个选项文档,则 db.collection.createIndex() 操作将失败。
考虑以下 db.collection.createIndex() 操作
db.collection.createIndex( { "a": 1 }, { unique: true, sparse: true, expireAfterSeconds: 3600 } )
如果选项规范被分成多个文档,例如:{ unique: true }, { sparse: true, expireAfterSeconds: 3600 },则索引创建操作将失败。
所有索引类型的选项
以下选项对所有索引类型均可用,除非另有说明
参数 | 类型 | 描述 | |
|---|---|---|---|
unique | 布尔值 | ||
name | 字符串 | 可选。索引的名称。如果未指定,MongoDB 将通过连接索引字段名称和排序顺序来生成索引名称。 | |
partialFilterExpression | 文档 | ||
稀疏 | 布尔值 | ||
expireAfterSeconds | 整数 | 可选。指定一个值(以秒为单位),作为生存时间(TTL),以控制 MongoDB 在此集合中保留文档的时间。此选项仅适用于 TTL 索引。有关更多信息,请参阅 通过设置 TTL 从集合中过期数据。 如果您使用的是 MongoDB 5.0 之前创建的 TTL 索引,或者您想将 MongDB 5.0 中创建的数据与低于 5.0 的安装同步,请参阅 使用 NaN 配置的索引,以避免配置错误问题。 TTL 索引 | |
布尔值 | 可选。一个标志,用于确定索引是否从查询计划器中被隐藏(hidden)。隐藏的索引不作为查询计划选择的一部分进行评估。 默认值为 | ||
storageEngine | 文档 | 可选。允许用户在创建索引时按索引配置存储引擎。
在创建索引时指定的存储引擎配置选项将被验证并记录到复制过程中的 oplog 中,以支持使用不同存储引擎的副本集。 |
排序选项
参数 | 类型 | 描述 | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
排序 | 文档 | 可选。指定索引的排序。 排序允许用户指定字符串比较的语言特定规则,例如字母大小写和重音符号的规则。 如果在集合级别指定了排序,那么
排序选项具有以下语法 指定排序时, |
以下索引仅支持简单的二进制比较,不支持排序:
提示
要在具有非简单排序的集合上创建text或2d索引,必须在创建索引时显式指定{collation: {locale: "simple"} }。
排序和索引使用
如果在集合级别指定了排序,那么
如果创建索引时未指定排序,MongoDB将使用集合的默认排序创建索引。
如果创建索引时指定了排序,MongoDB将使用指定的排序创建索引。
提示
通过指定排序strength为1或2,可以创建一个不区分大小写的索引。排序强度为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”,无论您设置的 强度 参数的值如何。
text 索引的选项
以下选项仅适用于 text 索引
参数 | 类型 | 描述 |
|---|---|---|
权重 | 文档 | 可选。对于文本索引,包含字段和权重对的文档。权重是一个范围从1到99,999的整数,表示字段相对于其他索引字段在评分方面的相对重要性。您可以指定一些或所有索引字段的权重。请参阅在自托管部署中分配文本搜索结果的权重以调整评分。默认值为 从MongoDB 5.0开始,仅允许文本索引使用权重选项。 |
default_language | 字符串 | 可选。对于文本索引,确定停用词列表以及词干提取器和分词器规则的语言。有关可用语言,请参阅自托管部署上的文本搜索语言,有关更多信息示例,请参阅在自托管部署上指定文本索引的默认语言。默认值为 english。 |
language_override | 字符串 | |
textIndexVersion | 整数 | 可选。《text》索引版本号。用户可以使用此选项覆盖默认版本号。 有关可用版本,请参阅自托管部署上的文本索引版本。 |
2dsphere索引的选项
以下选项仅适用于2dsphere索引
参数 | 类型 | 描述 |
|---|---|---|
2dsphereIndexVersion | 整数 | 可选。《2dsphere》索引版本号。用户可以使用此选项覆盖默认版本号。 有关可用版本,请参阅2dsphere索引。 |
2D索引的选项
以下选项仅适用于2d索引
参数 | 类型 | 描述 |
|---|---|---|
bits | 整数 | 可选。对于2d索引,存储的地理位置数据的geohash值的精度数。 bits值范围从1到32,默认值是26。 |
min | 数字 | 可选。对于2d索引,经纬度值的下限(包含)。默认值是-180.0。 |
max | 数字 | 可选。对于2d索引,经纬度值的上限(包含)。默认值是180.0。 |
wildcard索引的选项
通配符索引可以使用wildcardProjection选项。
参数 | 类型 | 描述 | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
wildcardProjection | 文档 | 可选。允许用户在通配符索引中包含或排除特定的字段路径。 此选项仅在您在所有文档字段上创建通配符索引时有效。当您在特定的字段路径及其子字段上创建通配符索引时,不能指定
但是,您不能定义一个包含通配符字段和常规(非通配符)字段中相同字段的索引。为了正确定义索引,请使用
选项
默认情况下,通配符索引会省略
|
行为
重建现有索引
如果您为已存在的索引调用 db.collection.createIndex(),MongoDB 不会重建该索引。
索引选项
非归并和非隐藏选项
除了归并选项之外,如果您使用一组索引选项创建了一个索引,然后尝试使用不同的索引选项重新创建相同的索引,MongoDB不会更改选项也不会重新创建索引。
可以更改隐藏选项,而无需删除并重新创建索引。请参阅隐藏选项。
要更改其他索引选项,在运行带有新选项的db.collection.createIndex()之前,先使用db.collection.dropIndex()删除现有索引。
归并选项
您可以在相同的键(键集)上创建多个具有不同排序规则的索引。为了创建具有相同键模式但不同排序规则的索引,您必须提供唯一的索引名称。
隐藏选项
要隐藏或取消隐藏现有索引,可以使用以下 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 } );
事务
如果事务不是跨分片写事务,则可以在分布式事务内创建集合和索引。不 是跨分片写事务。
要在事务中使用 db.collection.createIndex(),事务必须使用读取关注点 "local"。如果您指定了除 "local" 之外的读取关注点级别,事务将失败。
索引构建
已更改在版本7.1.
从MongoDB 7.1版本开始,索引构建得到改进,错误报告速度更快,容错能力更强。您还可以使用新的 indexBuildMinAvailableDiskSpaceMB 参数设置索引构建所需的最低可用磁盘空间,当磁盘空间过低时将停止索引构建。
以下表格比较了从MongoDB 7.1版本开始与早期版本的索引构建行为。
从MongoDB 7.1版本开始的索引构建行为 | 早期MongoDB版本的索引构建行为 |
|---|---|
在集合扫描阶段发现的索引错误(除重复键错误外)将立即返回,然后停止索引构建。早期MongoDB版本在提交阶段返回错误,该阶段发生在索引构建的末尾。MongoDB 7.1有助于快速诊断索引错误。例如,如果发现不兼容的索引值格式,错误将立即返回给您。 | 与MongoDB 7.1相比,索引构建错误可能需要很长时间才能返回,因为错误是在提交阶段,即在索引构建的末尾返回的。 |
索引构建错误可能导致次要成员崩溃。 | |
改进了索引构建的磁盘空间管理。如果可用磁盘空间低于在 indexBuildMinAvailableDiskSpaceMB 参数中指定的最低值,索引构建可能会自动停止。如果成员已经投票提交索引,则不会停止索引构建。 | 如果可用磁盘空间不足,则不会停止索引构建。 |
示例
在单个字段上创建升序索引
以下示例在字段 orderDate 上创建一个升序索引。
db.collection.createIndex( { orderDate: 1 } )
如果 keys 文档指定了多个字段,那么 createIndex() 会创建一个 复合索引。
在多个字段上创建索引
以下示例在字段 orderDate(升序)和字段 zipcode(降序)上创建一个复合索引。
db.collection.createIndex( { orderDate: 1, zipcode: -1 } )
复合索引可以包括一个单独的 哈希 字段。复合哈希索引需要将 featureCompatibilityVersion 设置为至少 5.0。
以下示例在字段 state(升序)和字段 zipcode(哈希)上创建一个复合索引。
db.collection.createIndex( { "state" : 1, "zipcode" : "hashed" } )
复合索引中字段的顺序对于支持使用索引进行 sort() 操作非常重要。
创建指定校对的索引
以下示例创建了一个名为 category_fr 的索引。此示例使用指定了区域设置 fr 和比较强度 2 的 校对 创建索引
db.collection.createIndex( { category: 1 }, { name: "category_fr", collation: { locale: "fr", strength: 2 } } )
以下示例创建了一个复合索引 date_category_fr,其中包含一个 校对。此校对仅应用于具有字符串值的索引键。
db.collection.createIndex( { orderDate: 1, category: 1 }, { name: "date_category_fr", collation: { locale: "fr", strength: 2 } } )
校对应用于值为字符串的索引键。
对于使用相同校对规则的索引键上的查询或排序操作,MongoDB 可以使用该索引。有关详细信息,请参阅 校对和索引使用。
创建通配符索引
默认情况下,通配符索引会省略
_id字段。若要在通配符索引中包含_id字段,必须在wildcardProjection文档中显式包含它。{ "wildcardProjection" : { "_id" : 1, "<field>" : 0|1 } } wildcardProjection文档中的所有语句必须是包含或排除语句。您也可以使用排除语句来包含_id字段。这是规则的唯一例外。通配符索引不支持
通配符索引是 稀疏索引。当索引字段不存在时,不支持查询。如果通配符字段有
null值,则通配符索引将索引文档。从 MongoDB 7.0 开始,通配符索引支持升序(
1)和降序(-1)排序顺序。早期版本仅支持升序顺序。
有关更多信息,请参阅
有关示例,请参阅
在单个字段路径上创建通配符索引
考虑一个名为 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.createIndex( { "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.createIndex( { "$**" : 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.createIndex( { "$**" : 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.createIndex( { "$**" : 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的更多信息,请参阅参数文档。
使用提交法定数创建索引
副本集或分片集群中的索引构建会在所有承载数据的副本集成员上同时进行。对于分片集群,索引构建仅发生在包含被索引集合数据的分片上。主节点需要一定数量的承载数据的voting成员(即提交法定数),包括自身,必须在标记索引为可使用之前完成构建。有关更多信息,请参阅复制的索引构建。
要设置提交法定数,请使用createIndex()来指定commitQuorum值。
commitQuorum指定了在主节点执行提交之前,必须准备好提交索引构建的承载数据的投票成员的数量或成员。
以下操作创建了一个具有提交法定数的索引"majority",即数据承载投票成员的简单多数。
db.getSiblingDB("examples").invoices.createIndex( { "invoices" : 1 }, { }, "majority" )
主节点只有在简单多数的数据承载投票成员“投票”提交索引构建后才会将索引构建标记为就绪。有关索引构建和投票过程的更多信息,请参阅复制的索引构建。
附加信息
请参阅此手册的索引部分以获取MongoDB中索引和索引的完整文档。
使用
db.collection.getIndexes()查看集合现有索引的规范。请参阅自托管部署上的文本索引以了解创建
文本索引的详细信息。请参阅地理空间索引以了解地理空间查询。
请参阅TTL索引以了解数据的过期。