本文档列出了MongoDB的硬限制和软限制。除非另有说明,否则限制应用于MongoDB Atlas和自托管部署。
MongoDB一般限制
集合和数据库大小
MongoDB不对集合或数据库大小施加硬性限制。最大大小取决于托管文件系统:
ext4 :最大文件大小16 TiB
XFS:最大文件大小为 8艾字节 (EiB)
要超越文件系统或硬件限制,请对非 Atlas 部署使用 分片。对于接近这些限制或遇到性能瓶颈的本地集合, MongoDB建议分片或迁移到支持自动伸缩的MongoDB Atlas 。
对集合分片, MongoDB会根据分片键确定初始数据块段范围:
默认
chunkSize:128 MB典型的平均分片键大小:16 字节
BSON 文档
- BSON 文档大小
BSON文档大小的上限为 16 MB。
最大文档大小有助于确保单个文档在传输过程中不会使用过多的RAM或过多的带宽。要存储大于最大大小的文档, MongoDB提供了GridFS API。有关GridFS的详细信息,请参阅
mongofiles和驾驶员文档。
- BSON 文档的嵌套深度
MongoDB 支持 BSON 文档的嵌套级别不超过 100 个。每个对象或数组都会添加一个级别。
命名限制
- 数据库名称中大小写的使用
不要依赖大小写来区分数据库。创建数据库后,引用该数据库时请使用一致的大小写。
示例,您不能使用两个具有
salesData和SalesData等名称的数据库。如果创建salesData数据库,请勿使用salesdata或SalesData等备用大小写来引用该数据库。
- 对集合名称的限制
集合名称应以下划线或字母字符开头,并且不能:
包含
$为空字符串(例如
"")包含空字符
以
system.前缀开头(保留以供内部使用)contain
.system.
如果集合名称包含特殊字符(例如下划线字符)或以数字开头,则要访问该集合,请使用
mongosh中的db.getCollection()方法或驱动程序的类似方法。未分片集合和视图的命名空间长度限制为 255 字节,分片集合的命名空间长度限制为 235 字节。对于集合或视图,命名空间包括数据库名称、点 (
.) 分隔符和集合/视图名称(如<database>.<collection>)。
命名警告
警告
请谨慎使用。本节中的问题可能会导致数据丢失或损坏。
- MongoDB 不支持重复的字段名称
MongoDB 查询语言对创建或更新字段名称有以下限制:
MongoDB 不支持插入字段名称重复的文档。虽然某些 BSON 构建器可能支持创建此类文档,但 MongoDB 并不支持这些操作,即使插入成功或看似成功也是如此。
即使更新成功或看似成功,也不支持更新具有重复字段名称的文档。
示例,通过MongoDB驱动程序插入具有重复字段名称的BSON文档可能会导致驱动程序在插入之前静默删除重复值,或者可能导致插入包含重复字段的无效文档。查询这些文档会导致结果不一致。
从MongoDB6.1 开始,要查看文档是否具有重复的字段名称,请使用
validate命令并将full字段设立为true。在任何MongoDB版本中,使用$objectToArray聚合操作符可查看文档是否具有重复的字段名称。
- 避免不明确的字段名称
请勿使用与嵌入字段的点表示法相同的字段名称。如果某个文档有嵌入字段
{ "a" : { "b": ... } },则该集合中的其他文档不应具有顶级字段"a.b"。如果您可以以相同的方式引用嵌入式字段和顶级字段,索引和分片操作将发生在嵌入式字段上。当集合具有以相同方式引用的嵌入式字段时,您无法对顶级字段
"a.b"索引或分片。示例,如果您的集合包含同时具有嵌入式字段
{ "a" : { "b": ... } }和顶级字段"a.b"的文档,索引和分片操作将在嵌入式字段上进行。当您的集合还包含嵌入式字段{ "a" : { "b": ... } }时,无法对顶级字段"a.b"进行索引或分片。
- 关于美元符号 (``$``) 和句点 (``.``) 的导入和导出问题
从 MongoDB 5.0 开始,文档字段名称可以是美元 (
$) 前缀,并且可以包含句点 (.)。但是,对于使用这些字符的字段名称,mongoimport和mongoexport在某些情况下可能无法按预期运行。MongoDB 扩展 JSON v2 无法区分类型封装器和碰巧与类型封装器同名的字段。不要在相应的 BSON 表示可能包含美元 (
$) 前缀键的上下文中使用扩展 JSON 格式。DBRef 机制是该一般规则的例外。在字段名中使用带句号 (
.) 的mongoimport和mongoexport也有限制。由于 CSV 文件使用句点 (.) 表示数据层次结构,因此字段名称中的句点 (.) 会被误读为嵌套级别。
- 美元符号 (``$``) 和句点 (``.``) 可能导致数据丢失
使用以美元符号 (
$) 为前缀的字段名称或包含句点 (.) 的字段名称时,如果在 MongoDB 5.0 之前的服务器上将这些字段名称与未确认的写入(写关注w=0)结合使用,则数据丢失的可能性很小。运行
insert、update和findAndModify命令时,兼容 5.0 的驱动程序会取消对使用字段名称以美元 ($) 为前缀或包含句点 (.) 的文档的限制。在早期的驱动程序版本中,这些字段名称会产生客户端错误。无论驱动程序连接到哪个服务器版本,这些限制均会被删除。如果 5.0 驱动程序将文档发送到较旧的服务器,则会拒绝该文档,而不会发送错误。
索引
- 具有 2dsphere 索引的字段只能保存几何图形
具有 2dsphere 索引的字段必须以坐标对或 GeoJSON 数据的形式保存几何数据。如果您尝试在
2dsphere索引字段中插入包含非几何数据的文档,或者在索引字段包含非几何数据的集合上构建2dsphere索引,则操作会失败。
- 2dsphere 索引键的有限数量
为了生成 2dsphere 索引键,
mongod将 GeoJSON 形状映射到内部表示形式。生成的内部表示可能是很大的值数组。当
mongod为保存数组的字段生成索引键时,mongod会为每个数组元素生成一个索引键。对于复合索引,mongod会计算为每个字段生成的键集的笛卡尔积。如果两个集合都很大,那么计算笛卡尔积可能会导致操作超出内存限制。indexMaxNumGeneratedKeysPerDocument限制为单个文档生成的最大键数,防止出现内存不足错误。默认每个文档 100000 个索引键。可以提高限制,但如果某个操作需要的键数超过indexMaxNumGeneratedKeysPerDocument参数指定的键数,则操作就会失败。
- WiredTiger 存储引擎从涵盖查询返回的 NaN 值始终为 double 类型
如果索引覆盖的查询返回的字段值为
NaN,则该NaN值的类型始终为double。
- Multikey Index
多键索引无法涵盖对数组字段的查询。
- 地理空间索引
地理空间索引无法涵盖查询。
- 索引构建中的内存使用情况
createIndexes支持在集合上构建一个或多个索引。createIndexes使用内存和磁盘上的临时文件的组合来构建索引。默认内存限制为每个createIndexes命令 200 兆字节,由该命令中构建的所有索引平均共享。示例,如果您使用一个createIndexes命令构建10 个索引,则在使用默认内存限制 200 时, MongoDB会为每个索引分配 20 MB 的内存用于索引构建进程。当达到内存限制时, MongoDB会在--dbpath内的_tmp子目录中创建临时文件以完成构建。使用 参数调整内存限制。仅在极少数情况下才需要增加此参数,例如当您运行单个
maxIndexBuildMemoryUsageMegabytes命令同时运行多个索引构建时,或者对大于createIndexes500GB 的数据集索引时。每个
createIndexes命令的限制为maxIndexBuildMemoryUsageMegabytes。使用默认maxNumActiveUserIndexBuilds3 时,所有并发索引构建的总内存使用量最多可能达到maxIndexBuildMemoryUsageMegabytes值的 3 倍。maxIndexBuildMemoryUsageMegabytes限制适用于由用户命令(如createIndexes)或管理进程(如 初始同步)启动的所有索引构建。初始同步一次仅填充一个集合,并且不存在超过内存限制的风险。但是,用户可以同时在多个数据库中的多个集合上启动索引构建。
- 排序规则和索引类型
以下索引只支持简单的二进制比较,不支持排序规则:
提示
要在具有非简单排序规则的集合上创建
text或2d索引,您必须在创建索引时显式指定{collation: {locale: "simple"} }。
排序
固定大小集合
- 固定大小集合的最大文档数
如果您使用
create的max参数指定固定大小集合中的最大文档数,则该值必须小于 2 31 个文档。如果在创建固定大小集合时未指定最大文档数,则对文档数没有限制。
副本集
- 副本集投票节点数
一个副本集最多可以有 7 个投票成员。对于成员总数超过 7 的副本集,请参阅无投票权的成员。
- 自动创建的 oplog 的最大大小
如果您没有明确指定oplog大小(即使用
oplogSizeMB或 ),--oplogSizeMongoDB将创建不大于50 GB 的oplog 。 []1[1] oplog 的大小可能会超过其配置的大小限制,从而避免删除 majority commit point。
分片集群
- 分片集合中的单份文档修改操作
要对指定
justOne或multi: false选项的分片集合使用update和remove()操作:如果您仅针对一个分片,则可以在查询规范中使用部分分片键,或者
您可以在查询规范中提供分片键或
_id字段。
- 每个迁移范围的最大文档数量
默认情况下,如果一个范围中的文档数大于配置的范围大小除以平均文档大小的结果的 2 倍,则 MongoDB 无法移动该范围。如果 MongoDB 可以移动数据段的子范围并将大小减小到小于该值,则负载均衡器可以迁移范围以实现该目的。
db.collection.stats()包括avgObjSize字段,它表示集合中的平均文档大小。对于太大而无法迁移的数据段:
负载均衡器设置
attemptToBalanceJumboChunks允许负载均衡器迁移太大而无法移动的数据段,只要这些数据段未标记为 jumbo。有关详情,请参阅超出大小限制的负载均衡范围。在发出
moveRange和moveChunk命令时,可以指定 forceJumbo 选项以允许迁移太大而无法移动的范围。范围可能标记为巨大,也可能未标记为巨大。
分片键
操作
- 排序操作
如果MongoDB无法使用一个或多个索引来获取排序顺序,则MongoDB必须对数据执行内存排序操作。
有关排序和索引使用的更多信息,请参阅排序和索引使用。
- 聚合管道阶段
MongoDB 将单个管道中允许的聚合管道阶段数量限制为 1000 个。
如果聚合管道在解析之前或之后超过阶段限制,您会收到错误消息。
- 聚合管道内存
从 MongoDB 6.0 开始,
allowDiskUseByDefault参数可控制需要 100 MB 以上内存容量来执行的管道阶段是否默认会将临时文件写入磁盘。如果将
allowDiskUseByDefault设为true,则默认情况下,需要 100 MB 以上内存容量的管道阶段会将临时文件写入磁盘。您可以使用{ allowDiskUse: false }选项来为特定的find或aggregate命令禁用将临时文件写入磁盘的功能。如果
allowDiskUseByDefault设置为false,则默认情况下,需要超过 100 MB 的内存才能执行的管道阶段会引发错误。您可以使用{ allowDiskUse: true }选项来为特定find或aggregate启用向磁盘写入临时文件的功能。
$search聚合阶段不限于 100 MB 的 RAM,因为它在单独的进程中运行。当 allowDiskUse 为
true时,可将临时文件写入磁盘的阶段示例如下:注意
管道阶段对文档流进行操作,每个管道阶段接收文档,对其进行处理,然后输出结果文档。
某些阶段在处理完所有传入文档之前无法输出任何文档。这些管道阶段必须将其阶段输出保留在 RAM 中,直到处理完所有传入文档。因此,这些管道阶段所需的空间可能超过 100 MB 的限制。
如果某一
$sort管道阶段的结果超过此限制,则可考虑添加一个 $limit 阶段。
- 聚合和读关注
$out阶段不能与读关注"linearizable"一起使用。如果为db.collection.aggregate()指定"linearizable"读关注,则不能将$out阶段包括在管道中。$merge阶段不能与读关注"linearizable"一起使用。换言之,如果您为db.collection.aggregate()指定"linearizable"读关注,则不能将$merge阶段包括在管道中。
- GeoJSON 多边形的面积
对于
$geoIntersects或$geoWithin,如果指定的单环多边形的面积大于单半球,则应在$geometry表达式中包含自定义 MongoDB 坐标参考系。否则,$geoIntersects或$geoWithin将查询互补几何体。对于面积大于半球的所有其他 GeoJSON 多边形,$geoIntersects或$geoWithin将查询互补几何体。
- 多文档事务
对于多文档事务:
可以在事务中创建集合和索引。有关详细信息,请参阅在事务中创建集合和索引
事务中使用的集合可以位于不同的数据库中。
注意
您无法在跨分片写事务中创建新集合。例如,如果您在一个分片中写入一个现有集合,并在另一个分片中隐式创建一个集合,MongoDB 将无法在同一事务中执行这两个操作。
不能写入固定大小集合。
从固定大小集合读取时不能使用读关注
"snapshot"。(从 MongoDB 5.0 开始)不能在
config、admin或local数据库中读取/写入集合。不能写入
system.*集合。不能使用
explain或类似命令返回受支持操作的查询计划。
不能将
killCursors命令指定为ACID 事务中的第一个操作。此外,如果在ACID 事务中运行
killCursors命令,服务器会立即停止指定的游标。它不会等待ACID 事务提交。
事务中不允许执行以下操作:
在跨分片写事务中创建新集合。例如,如果您在一个分片中写入一个现有集合,并在另一个分片中隐式创建一个集合,那么 MongoDB 将无法在同一事务中执行这两项操作。
使用
"local"以外的读关注级别时,显式创建集合(例如db.createCollection()方法)和索引(例如db.collection.createIndexes()和db.collection.createIndex()方法)。listCollections和listIndexes命令及其辅助方法。其他非 CRUD 和非信息性操作(例如
createUser、getParameter和count)及其辅助程序。并行操作。要同时更新多个命名空间,请考虑改用
bulkWrite命令。
事务具有由
transactionLifetimeLimitSeconds指定的生命周期限制。默认为 60 秒。
- 写入命令批处理限制大小
驾驶员可以处理的写入操作数量没有限制。驱动程序根据 maxWriteBatchSize(为, 100000,且无法修改)将数据分组为批次。如果该批处理包含超过100 、000 个操作,则驾驶员会将该批处理分成多个较小的组,且其计数小于或等于 maxWriteBatchSize。示例,如果操作包含, 250000操作,则驾驶员会创建三个批处理:两个包含,100 00050操作,一个包含,000 操作。
- 视图
视图定义
pipeline不能包含$out或$merge阶段。这一限制也适用于嵌入式管道,例如在$lookup或$facet阶段中使用的管道。视图有以下操作限制:
视图为只读。
您无法重命名视图。
视图上的
find()操作不支持以下 find 命令投影操作符:视图不支持
$text。视图不支持 map-reduce 操作。
- 投影限制
- 以 ``$`` 为前缀的字段路径限制
find()和findAndModify()投影无法项目以$开头的字段,但 DBRef 字段除外。例如,以下操作无效:
db.inventory.find( {}, { "$instock.warehouse": 0, "$item": 0, "detail.$price": 1 } )
- ``$`` 位置操作符放置限制
$投影操作符只能出现在字段路径的末尾,例如"field.$"或"fieldA.fieldB.$"。例如,以下操作无效:
db.inventory.find( { }, { "instock.$.qty": 1 } ) 要解决此问题,请删除字段路径中位于
$投影运算符之后的部分。
- 空字段名称投影限制
find()和findAndModify()投影不能包含空字段名称的投影。例如,以下操作无效:
db.inventory.find( { }, { "": 0 } ) 在以前的版本中,MongoDB 会将空字段的包含/排除操作视为对不存在字段的投影。
- 路径冲突:嵌入式文档及其字段
您不能使用嵌入文档的任何字段来投影嵌入式文档。
例如,考虑一个文档集合
inventory,其中的文档包含size字段:{ ..., size: { h: 10, w: 15.25, uom: "cm" }, ... } 以下操作会失败并显示
Path collision错误,因为它会尝试同时投影size文档和size.uom字段:db.inventory.find( {}, { size: 1, "size.uom": 1 } ) 在以前的版本中,嵌入式文档与其字段之间的最后投影决定实际投影:
如果嵌入式文档的投影位于其字段的所有投影之后,则 MongoDB 会投影该嵌入式文档。例如,投影文档
{ "size.uom": 1, size: 1 }生成与投影文档{ size: 1 }相同的结果。如果嵌入式文档的投影位于其任何字段的投影之前,MongoDB 会投影指定的一个或多个字段。例如,投影文档
{ "size.uom": 1, size: 1, "size.h": 1 }生成与投影文档{ "size.uom": 1, "size.h": 1 }相同的结果。
- 路径冲突:数组和嵌入式字段的 ``$slice``
find()和findAndModify()投影不能同时包含大量的$slice和嵌入该大量中的字段。例如,考虑包含数组字段
instock的集合inventory:{ ..., instock: [ { warehouse: "A", qty: 35 }, { warehouse: "B", qty: 15 }, { warehouse: "C", qty: 35 } ], ... } 以下操作失败并显示
Path collision错误:db.inventory.find( {}, { "instock": { $slice: 1 }, "instock.warehouse": 0 } ) 在以前的版本中,投影应用两个投影并返回
instock数组中的第一个元素 ($slice: 1),但抑制投影元素中的warehouse字段。从 MongoDB 4.4 开始,要获得相同的结果,请使用具有两个独立$project阶段的db.collection.aggregate()方法。
- ``$`` 位置操作符和 ``$slice`` 限制
find()和findAndModify()投影不能包含$slice投影表达式作为$投影表达式的一部分。例如,以下操作无效:
db.inventory.find( { "instock.qty": { $gt: 25 } }, { "instock.$": { $slice: 1 } } ) 在之前的版本中,MongoDB 返回
instock数组中符合查询条件的第一个元素(instock.$);即位置投影"instock.$"优先,而$slice:1是无需操作。"instock.$": { $slice: 1 }不排除任何其他文档字段。
会话
- 会话和 $external 用户名限制
要对
$external身份验证用户(Kerberos、LDAP 或 X.509 用户)使用客户端会话和因果一致性保证,用户名不能大于 10k 字节。
- 会话空闲超时
连续 分钟未收到读取或写入操作或未使用30
refreshSessions刷新的会话将被标记为已过期,并且可由MongoDB 服务器关闭。关闭会话会终止所有进行中的操作和打开的游标,包括配置了大于noCursorTimeout()maxTimeMS()30分钟的 或 的操作和游标。长时间运行的游标操作
对于返回空闲时间可能超过30 分钟的游标的操作,请使用
Mongo.startSession()在显式会话中发出该操作,并使用refreshSessions定期刷新会话。示例:var session = db.getMongo().startSession() var sessionId = session sessionId // show the sessionId var cursor = session.getDatabase("examples").getCollection("data").find().noCursorTimeout() var refreshTimestamp = new Date() // take note of time at operation start while (cursor.hasNext()) { // Check if more than 5 minutes have passed since the last refresh if ( (new Date()-refreshTimestamp)/1000 > 300 ) { print("refreshing session") db.adminCommand({"refreshSessions" : [sessionId]}) refreshTimestamp = new Date() } // process cursor normally } refreshSessions此示例每5 分钟使用一次 ,以防止30 分钟的空闲超时。游标无限期地保持打开状态。
仅限 Atlas 的限制
以下限制仅适用于 MongoDB Atlas 中托管的部署。如果其中任何限制对您的组织造成问题,请联系 Atlas 支持部门。
集群限制
按集群层划分的连接限制
连接限制应用于每个节点
集群层的连接限制:
注意
MongoDB Atlas 为每个集群保留少量连接,用于支持 Atlas 服务。
多云连接限制
如果您通过私有连接连接到多云MongoDB Atlas部署,则只能访问权限您连接的同一云提供商中的节点。该云提供商在其地区中可能没有主节点 (primary node in the replica set)节点。发生这种情况时,请在连接字符串中指定从节点(secondary node from replica set)读取偏好(read preference)模式。
要通过私有连接访问权限当前提供商的所有节点,请为其余每个云提供商配置连接MongoDB Atlas 的VPN 或私有端点。
集合和索引限制
MongoDB Atlas 群集中的集合数量没有硬性限制。但是,集合和索引较多时,性能会下降。集合越大,影响越大。
按集群层推荐的集合和索引的最大组合数:
集群层 | 建议的最大值 |
|---|---|
| 5,000 个集合和索引 |
| 10,000 个集合和索引 |
| 100,000 个集合和索引 |
组织和项目限制
MongoDB Atlas 部署具有以下组织和项目限制:
组件 | Limit |
|---|---|
100 | |
500 | |
每个组织的Atlas用户数 | 500 |
每个组织的API密钥数 | 500 |
200 | |
每个团队的用户数 | 250 |
每个项目的团队数 | 100 |
每个组织的团队数 | 250 |
每个用户的团队数 | 100 |
每个用户的组织数 | 250 |
每个跨组织配置的关联组织数 | 250 |
每个项目的集群数 | 25 |
每个组织的项目数 | 250 |
100 | |
为每个数据库用户分配的角色数 | 100 |
按组织小时计费 | $50 |
25 | |
每个项目的网络对等互连连接总数 | |
每个项目的待处理网络对等连接 | 25 |
每个地区的 AWS PrivateLink 可寻址目标数 | 50 |
每个地区的 Azure PrivateLink 可寻址目标 | 150 |
每个 MongoDB Atlas 托管的全球集群项目的唯一分片键 | |
| 1 |
500 |
服务帐户限制
组件 | Limit |
|---|---|
200 | |
200 | |
2 | |
100 |
标签限制
MongoDB Atlas 会限制长度并为以下组件标签强制执行 ReGex 要求:
组件 | 字符限制 | 正则表达式模式 |
|---|---|---|
集群名称 | 64[]2 |
|
项目名称 | 64 |
|
组织名称 | 64 |
|
API 密钥说明 | 250 |
| [2] | 如果启用了仅对等互连模式,集群名称字符数限制为 23。 |
| [3] | MongoDB Atlas 使用集群名称的前 23 个字符。这些字符在该集群的项目内必须是唯一的。少于 23 个字符的集群名称不能以连字符 (-) 结尾。超过 23 个字符的集群名称不能将连字符作为第 23 个字符。 |
| [4] | ( 1 , 2 ) 组织和项目名称可以包含任何 Unicode 字母或数字以及以下标点符号:-_.(),:&@+'。 |
免费和 Flex 集群限制
其他限制应用于MongoDB Atlas免费集群和 Flex 集群。要学习;了解详情,请参阅:
命令限制
MongoDB Atlas不支持某些MongoDB命令。此外,某些命令仅在MongoDB Atlas免费集群中受支持。要学习;了解详情,请参阅: