On this page
MongoDB 2.6 中的兼容性更改
在本页面
以下 2.6 更改可能会影响与旧版本 MongoDB 的兼容性。有关 2.6 更改的完整列表,请参见MongoDB 2.6 发行说明。
Index Changes
强制执行索引密钥长度限制
Description
- MongoDB 2.6 对
index key
实施了更严格的限制。
- MongoDB 2.6 对
如果现有文档中的索引键超出限制,则创建索引将出错:
db.collection.ensureIndex(),db.collection.reIndex(),compact和repairDatabase会出错,并且不会创建索引。 MongoDB 的早期版本将创建索引,但不会为此类文档构建索引。
由于db.collection.reIndex(),compact和repairDatabase会从集合中删除所有索引,然后按 Sequences 重新创建它们,因此索引键限制产生的错误会阻止这些操作为该集合重建任何剩余的索引,如果使用repairDatabase命令,从 continue 进行其余的过程。
插入错误:
如果新文档的索引字段超出了其相应索引条目的限制,则db.collection.insert()和其他执行插入操作(例如db.collection.save()和db.collection.update()与
upsert
导致插入)将无法插入。 MongoDB 的早期版本将插入但不会索引此类文档。如果新文档的索引字段的索引条目超出限制,则mongorestore和mongoimport将无法插入。
更新将错误:
如果更新的值导致索引条目超过限制,则对索引字段执行的db.collection.update()和db.collection.save()操作将出错。
如果现有文档包含其索引条目超过限制的索引字段,则其他导致字段在磁盘上重新定位的字段的更新将出错。
块迁移将失败:
对于具有文档中包含索引字段超过索引限制的索引字段的文档块,迁移将失败。
如果不固定,该块将反复失败迁移,从而有效地停止了该集合的块平衡。或者,如果响应于迁移失败而发生了块拆分,则此响应将导致不必要的大量块和过多的配置数据库。
副本集的次要成员将警告:
次要对象将 continue 使用索引字段(其对应的索引条目超过初始同步限制)复制文档,但将在日志中显示警告。
辅助数据库允许对包含索引字段的集合进行索引构建和重建操作,该索引字段的相应索引条目超过了限制,但日志中有警告。
对于辅助目录为 2.6 版且主目录为 2.4 版的* mixed version *副本集,辅助目录将复制在 2.4 主目录上插入或更新的文档,但是如果文档包含其索引对应的索引字段,则会在日志中显示错误消息条目超过限制。
Solution
- 运行db.upgradeCheckAllDBs()查找违反此限制的当前密钥,并进行适当的更正。最好在升级之前运行测试;也就是说,将 2.6 mongo shell 连接到您的 MongoDB 2.4 数据库并运行该方法。
如果您已有数据集,并且想要禁用默认的索引键长度验证,以便可以在解决这些索引问题之前进行升级,请使用failIndexKeyTooLong参数。
索引规范验证字段名称
Description
- 在 MongoDB 2.6 中,当索引键引用一个空字段时,例如创建和重新索引操作将失败。
"a..b" : 1
或字段名以美元符号($
)开头。
- 在 MongoDB 2.6 中,当索引键引用一个空字段时,例如创建和重新索引操作将失败。
db.collection.ensureIndex()不会使用无效或空的键名创建新索引。
如果存在具有无效或空键名的索引,则db.collection.reIndex(),compact和repairDatabase将出错。
如果存在具有无效或空键名的索引,则块迁移将失败。
MongoDB 的早期版本允许索引。
Solution
- 运行db.upgradeCheckAllDBs()查找违反此限制的当前密钥,并进行适当的更正。最好在升级之前运行测试;也就是说,将 2.6 mongo shell 连接到您的 MongoDB 2.4 数据库并运行该方法。
确保索引和现有索引
Description
- db.collection.ensureIndex()现在出现错误:
如果尝试创建现有索引但具有不同的选项;例如在以下示例中,第二个db.collection.ensureIndex()将出错。
db.mycollection.ensureIndex( { x: 1 } )
db.mycollection.ensureIndex( { x: 1 }, { unique: 1 } )
- 如果指定的索引名称已经存在,但键的规格不同;例如在以下示例中,第二个db.collection.ensureIndex()将出错。
db.mycollection.ensureIndex( { a: 1 }, { name: "myIdx" } )
db.mycollection.ensureIndex( { z: 1 }, { name: "myIdx" } )
以前的版本没有创建索引,但是没有错误。
写入方法确认
Description
- mongo shell 写入方法db.collection.insert(),db.collection.update(),db.collection.save()和db.collection.remove()现在将write concern直接集成到方法中,而不是使用单独的getLastError命令来提供承认写,无论是在mongo shell 中交互运行还是在脚本中非交互运行。在以前的版本中,这些方法表现出“一劳永逸”的行为。 [1]
现在,使用这些方法的mongo shell 的现有脚本将 await 确认,这比以前的“即发即忘”行为花费的时间更长。
现在,write 方法将返回一个WriteResult对象,该对象包含操作结果,包括所有写错误和写关注错误,并且无需调用getLastError命令来获取结果的状态。有关详细信息,请参见db.collection.insert(),db.collection.update(),db.collection.save()和db.collection.remove()。
在分片环境中,mongos不再支持“即发即弃”行为。将数据写入分片群集时,这会限制吞吐量。
[1] | 在以前的版本中,当交互式使用mongo shell 时,mongo shell 在 write 方法之后会自动调用getLastError命令以提供对写入的确认。但是,除非脚本在 write 方法之后包含对getLastError命令的“显式”调用,否则脚本在以前的版本中将观察到“即发即弃”的行为。 |
在分片环境中,插入或修改文档组时,使用任何驱动程序或mongo shell 的应用程序应使用Bulk()方法以获得最佳性能。
例如,代替:
for (var i = 1; i <= 1000000; i++) {
db.test.insert( { x : i } );
}
在 MongoDB 2.6 中,替换为Bulk()操作:
var bulk = db.test.initializeUnorderedBulkOp();
for (var i = 1; i <= 1000000; i++) {
bulk.insert( { x : i} );
}
bulk.execute( { w: 1 } );
批量方法返回包含操作结果的BulkWriteResult对象。
See also
db.collection.aggregate() Change
Description
- mongo Shell 中的db.collection.aggregate()方法默认为将游标返回到结果集。此更改使聚合管道可以返回任何大小的结果集,并且需要迭代游标才能访问结果集。例如:
var myCursor = db.orders.aggregate( [
{
$group: {
_id: "$cust_id",
total: { $sum: "$price" }
}
}
] );
myCursor.forEach( function(x) { printjson (x); } );
早期版本返回的单个文档的字段results
包含结果集数组,但受BSON 文件大小限制。访问 MongoDB 早期版本中的结果集需要访问results
字段并迭代数组。例如:
var returnedDoc = db.orders.aggregate( [
{
$group: {
_id: "$cust_id",
total: { $sum: "$price" }
}
}
] );
var myArray = returnedDoc.result; // access the result field
myArray.forEach( function(x) { printjson (x); } );
Solution
- 更新当前希望db.collection.aggregate()返回带有
results
数组的文档来处理游标的脚本。
- 更新当前希望db.collection.aggregate()返回带有
写关注验证
Description
Solution
Security Changes
新的授权模型
Description
- MongoDB 2.6 authorization model更改了 MongoDB 存储和 Management 用户特权信息的方式:
升级之前,MongoDB 2.6 在 Management 数据库中至少需要一个用户。
使用旧模型的 MongoDB 版本无法创建/修改用户或创建用户定义的角色。
Solution
- 确保 Management 数据库中至少存在一个用户。如果 Management 数据库中没有用户,请添加用户。然后升级到 MongoDB 2.6. 最后,升级用户权限模型。参见将 MongoDB 升级到 2.6。
Important
在升级授权模型之前,您应该首先将 MongoDB 二进制文件升级到 2.6. 对于分片群集,请确保所有群集组件均为 2.6. 如果在任何数据库中都有用户,则在升级 MongoDB 二进制文件之前,请确保至少有一个userAdminAnyDatabase角色的用户在admin
数据库中。
SSL 证书主机名验证
Description
- 现在,SSL 证书验证将检查“公用名(
CN
)”和“使用者备用名(SAN
)”字段,以确保CN
或SAN
条目之一与服务器的主机名匹配。结果,如果您当前使用 SSL,并且当前 SSL 证书的CN
条目或所有SAN
条目都与主机名都不匹配,则升级到 2.6 版将导致 SSL 连接失败。
- 现在,SSL 证书验证将检查“公用名(
Solution
- 为了允许 continue 使用这些证书,MongoDB 提供了allowInvalidCertificates设置。该设置可用于:
mongo shell,支持 SSL 的 MongoDB 工具和 C 驱动程序绕过服务器证书的验证。
使用allowInvalidCertificates设置时,MongoDB 将使用无效证书记录为警告。
Warning
allowInvalidCertificates设置会绕过其他证书验证,例如检查过期和有效签名。
2dsphere 索引版本 2
Description
- MongoDB 2.6 引入了2dsphere index的版本 2.如果文档缺少
2dsphere
索引字段(或者该字段是null
或空数组),则 MongoDB 不会将文档的条目添加到2dsphere
索引中。对于插入,MongoDB 插入文档,但不添加到2dsphere
索引。
- MongoDB 2.6 引入了2dsphere index的版本 2.如果文档缺少
先前版本不会插入2dsphere
索引字段是null
或空数组的文档。对于缺少2dsphere
索引字段的文档,以前的版本将插入文档并为其构建索引。
Solution
- 若要还原为旧行为,请使用
{ "2dsphereIndexVersion" : 1 }
创建2dsphere
索引以创建版本 1 索引。但是,版本 1 索引不能使用新的 GeoJSON 几何。
- 若要还原为旧行为,请使用
See also
Log Messages
时间戳格式更改
Description
- 现在,每条消息都以时间格式变更中给出的时间戳格式开始。以前的版本使用
ctime
格式。
- 现在,每条消息都以时间格式变更中给出的时间戳格式开始。以前的版本使用
Solution
- MongoDB 添加了一个新选项
--timeStampFormat
,该选项支持ctime
,iso8601-utc
和iso8601-local
的时间戳格式(新的默认值)。
- MongoDB 添加了一个新选项
软件包配置更改
RPM/DEB 软件包的默认 bindIp
Description
- 在 RPM(Red Hat,CentOS,Fedora Linux 和衍生产品)和 DEB(Debian,Ubuntu 和衍生产品)中的正式 MongoDB 软件包中,默认的bindIp值将 MongoDB 组件附加到 localhost 接口* only *。这些软件包在默认配置文件(即
/etc/mongod.conf
)中设置了此默认设置。
- 在 RPM(Red Hat,CentOS,Fedora Linux 和衍生产品)和 DEB(Debian,Ubuntu 和衍生产品)中的正式 MongoDB 软件包中,默认的bindIp值将 MongoDB 组件附加到 localhost 接口* only *。这些软件包在默认配置文件(即
Solution
- 如果您使用这些软件包之一,并且没有修改默认的
/etc/mongod.conf
文件,则需要在升级之前或升级过程中设置bindIp。
- 如果您使用这些软件包之一,并且没有修改默认的
其他任何官方 MongoDB 软件包中均没有默认的bindIp设置。
SNMP Changes
Description
-
- MongoDB 的 IANA 企业标识符从 37601 更改为 34601.
-
MongoDB 将 MIB 字段名称
globalopcounts
更改为globalOpcounts
。Solution
-
- SNMP 监控的用户必须将其 SNMP 配置(即 MIB)从 37601 修改为 34601.
-
将对
globalopcounts
的引用更新为globalOpcounts
。
删除方法签名更改
Description
- db.collection.remove()需要查询文档作为参数。在以前的版本中,没有查询文档的方法调用会删除集合中的所有文档。
Solution
- 对于没有查询文档的现有db.collection.remove()调用,请修改这些调用以包括一个空文档
db.collection.remove({})
。
- 对于没有查询文档的现有db.collection.remove()调用,请修改这些调用以包括一个空文档
更新运算符语法验证
Description
-
- 更新运 operator(例如$ set)必须指定一个非空的操作数表达式。例如,以下表达式现在无效:
-
{ $set: { } }
- 更新运 operator(例如$ set)不能在更新语句中重复。例如,以下表达式无效:
{ $set: { a: 5 }, $set: { b: 5 } }
更新强制字段名称限制
Description
-
- 更新不能使用更新运 operator(例如$ set)定位具有空字段名称(即
""
)的字段。
- 更新不能使用更新运 operator(例如$ set)定位具有空字段名称(即
-
更新不再支持保存包含点(
.
)或以美元符号($
)开头的字段名称的字段名称。Solution
-
- 对于具有空名称
""
的字段的现有文档,请替换整个文档。有关替换现有文档的详细信息,请参见db.collection.update()和db.collection.save()。
- 对于具有空名称
-
对于名称字段包含点(
.
)的现有文档,请替换整个文档或unset替换该字段。要查找名称包含点的字段,请运行db.upgradeCheckAllDBs()。对于现有字段名称以美元符号(
$
),unset或rename开头的现有文档。要查找名称以美元符号开头的字段,请运行db.upgradeCheckAllDBs()。
有关写入操作协议的更改,请参见新的写操作协议;有关插入和更新操作的更改,请参见插入和更新改进。还请考虑字段名称限制的文档。
查询和排序更改
强制执行字段名称限制
Description
- 查询不能在名称以美元符号(
$
)开头的字段上指定条件。
- 查询不能在名称以美元符号(
Solution
- Unset或rename现有名称以美元符号(
$
)开头的字段。运行db.upgradeCheckAllDBs()以查找名称以美元符号开头的字段。
- Unset或rename现有名称以美元符号(
稀疏索引和不完整结果
Description
- 如果sparse index导致查询和排序操作的结果集不完整,除非hint()明确指定索引,否则 MongoDB 将不会使用该索引。
例如,除非明确提示,否则查询{ x: { $exists: false } }
将不再在x
字段上使用稀疏索引。
Solution
- 要覆盖使用稀疏索引并返回不完整结果的行为,请使用hint()显式指定索引。
有关详细说明新行为的示例,请参见集合上的稀疏索引无法返回完整结果。
sort()规范值
任何其他值都将导致错误。
以前的版本也接受true
或false
进行升序。
Solution
- 将使用
true
或false
的排序键值更新为1
。
- 将使用
skip()和_id 查询
Description
_id
字段上的相等匹配服从skip()。
在_id
字段上执行相等匹配时,以前的版本会忽略skip()。
describe()保留查询计划缓存
Description
- explain()不再清除为此query shape缓存的query plans。
在以前的版本中,explain()具有清除该查询形状的查询计划缓存的副作用。
See also
PlanCache()参考。
Geospatial Changes
$maxDistance Changes
Description
-
- 对于 GeoJSON 数据的$near查询,如果查询指定$maxDistance,则$maxDistance必须在$near文档内。
-
在以前的版本中,$maxDistance可以在$near文档之内或之外。
$maxDistance必须为正值。
Solution
-
- 更新$near文档之外当前具有$maxDistance的对 GeoJSON 数据的任何现有$near查询
-
更新$maxDistance为负值的所有现有查询。
Deprecated $uniqueDocs
Description
- MongoDB 2.6 弃用$uniqueDocs,并且当文档多次匹配查询时,地理空间查询不再返回重复的结果。
加强地理空间查询的验证
Description
- MongoDB 2.6 加强了对地理空间查询的验证,例如验证选项或 GeoJSON 规范,如果地理空间查询无效,则会出错。先前版本允许/忽略无效选项。
查询运算符更改
$ not 查询行为更改
Description
-
- 现在在索引字段上具有$not表达式的查询将匹配:
-
缺少索引字段的文档。以前的版本不会使用索引返回这些文档。
- 索引字段值与指定值的类型不同的文档。以前的版本不会使用索引返回这些文档。
例如,如果集合orders
包含以下文档:
{ _id: 1, status: "A", cust_id: "123", price: 40 }
{ _id: 2, status: "A", cust_id: "xyz", price: "N/A" }
{ _id: 3, status: "D", cust_id: "xyz" }
如果集合在price
字段上具有索引:
db.orders.ensureIndex( { price: 1 } )
以下查询使用索引来搜索price
不大于或等于50
的文档:
db.orders.find( { price: { $not: { $gte: 50 } } } )
在 2.6 中,查询返回以下文档:
{ "_id" : 3, "status" : "D", "cust_id" : "xyz" }
{ "_id" : 1, "status" : "A", "cust_id" : "123", "price" : 40 }
{ "_id" : 2, "status" : "A", "cust_id" : "xyz", "price" : "N/A" }
在以前的版本中,索引计划仅在字段类型与查询谓词类型匹配的情况下返回匹配的文档:
{ "_id" : 1, "status" : "A", "cust_id" : "123", "price" : 40 }
如果使用集合扫描,则以前的版本将返回与 2.6 中相同的结果。
- MongoDB 2.6 允许链接$not表达式。
空比较查询
Description
数组元素(例如
"a.b": null
)上的null
个相等条件不再匹配缺少嵌套字段a.b
(例如a: [ 2, 3 ]
)的文档。null
相等查询(即field: null
)现在将值undefined
的字段匹配。
$ all 操作员行为更改
Description
如果 array 字段包含嵌套数组(例如
field: [ "a", ["b"] ]
),并且嵌套字段上的$all是嵌套数组的元素(例如"field.1": { $all: [ "b" ] }
),则$all运算符不返回任何匹配项。早期版本将返回匹配项。
$ mod 运算符强制使用严格的语法
在以前的版本中,如果传递的数组包含一个元素,则$mod运算符将0
用作第二个元素,如果传递的数组包含两个以上的元素,则$mod会忽略除前两个元素之外的所有元素。以前的版本在传递空数组时会返回错误。
Solution
- 确保传递给$mod的数组恰好包含两个元素:
如果数组包含单个元素,请添加
0
作为第二个元素。如果数组包含两个以上的元素,请删除多余的元素。
$必须位于顶层
Description
- $where表达式现在只能位于顶层,不能嵌套在另一个表达式中,例如$elemMatch。
Solution
- 更新嵌套$where的现有查询。
$存在且值得注意
如果 MongoDB 服务器已禁用集合扫描,即notablescan,则$exists没有“索引解决方案”的查询将出错。
MinKey 和 MaxKey 查询
Description
MinKey
或MaxKey
的相等匹配不再匹配缺少该字段的文档。
具有$ elemMatch 的嵌套数组查询
Description
- $elemMatch查询运算符不再递归遍历嵌套数组。
例如,如果集合test
包含以下文档:
{ "_id": 1, "a" : [ [ 1, 2, 5 ] ] }
在 2.6 中,以下$elemMatch查询与文档不匹配*:
db.test.find( { a: { $elemMatch: { $gt: 1, $lt: 5 } } } )
Solution
- 更新依赖于旧行为的现有查询。
文本搜索兼容性
MongoDB 不支持在同时包含 2.4 版和 2.6 版分片的混合分片群集部署中使用$text查询运算符。有关升级说明,请参见将 MongoDB 升级到 2.6。
副本集/共享群集验证
分片名称检查刷新元数据
Description
- 对于分片群集,如果未明确设置分片名称,则 MongoDB 2.6 禁止分片刷新元数据。
对于同时包含 2.4 版和 2.6 版分片的混合分片群集部署,如果分片名称对于 2.6 版分片是未知的,则从 2.4 版分片**迁移到 2.6 版分片时,此更改可能导致错误。 。 MongoDB 不支持在混合分片群集部署中进行迁移。
副本集投票配置验证
Description
- 现在,MongoDB 不赞成给任何replica set成员多于一次投票。在配置过程中,
local.system.replset.members[n].votes
对于投票成员而言应仅为 1,对于非投票成员而言应为 0. MongoDB 将非 1 或 0 的值视为 1,并生成警告消息。
- 现在,MongoDB 不赞成给任何replica set成员多于一次投票。在配置过程中,
Solution
- 将
local.system.replset.members[n].votes
的值更新为 1 或 0 以外的值,以 1 或 0 为宜。
- 将
时间格式更改
现在,在许多输出中格式化时间数据时,MongoDB 现在使用iso8601-local
。此格式遵循模板YYYY-MM-DDTHH:mm:ss.mmm<+/-Offset>
。例如2014-03-04T20:13:38.944-0500
。
此更改会影响在“严格模式”下使用Extended JSON的所有 Client 端,例如mongoexport。