MongoDB 2.6中的兼容性变化

以下2.6更改可能会影响与旧版本MongoDB的兼容性。有关2.6更改的完整列表,请参阅MongoDB 2.6发布说明

索引更改

执行索引键长度限制

描述

MongoDB 2.6对指数密钥的限制实施了更强有力的执行

如果现有文档中的索引键超过限制,创建索引将出错:

  • db.collection.ensureIndex(),db.collection.reIndex()compactrepairDatabase将出错,不会创建索引。MongoDB的先前版本将创建索引,但不会索引此类文档。
  • 由于db.collection.reIndex()compact、andrepairDatabase从集合中删除所有索引,然后按顺序重新创建它们,因此索引键限制的错误阻止这些操作重建任何剩余的集合索引,在therapairDatabase命令的情况下,阻止它们继续使用该过程的相应者。

插入将错误:

  • db.collection.insert()如果新文档有一个索引字段,其相应索引条目超过限制,则执行插入的其他操作(例如db.collection.save()db.collection.update()带有upsert结果插入)将无法插入。MongoDB以前版本将插入但不会索引此类文档。
  • mongorestoremongoimport如果新文档有一个索引字段,其相应的索引条目超过限制,则将无法插入。

更新将出现错误:

  • db.collection.update()如果更新的值导致索引条目超过限制,则索引字段上的db.collection.save()操作将出错。
  • 如果现有文档包含索引输入超过限制的索引字段,则导致文档在磁盘上重新定位的其他字段的更新将出错。

块迁移将失败:

  • 对于具有索引字段的文档且索引条目超过限制的块,迁移将失败。
  • 如果保持未固定,块将反复失败迁移,从而有效地停止该集合的块平衡。或者,如果在响应迁移失败时发生块分割,这种响应将导致不必要的大量块和过大的配置数据库。

复制集的次要成员将警告:

  • 次要者将继续复制带有索引字段的文档,该字段的相应索引条目超过初始同步的限制,但将在日志中打印警告。
  • 次要允许索引构建和重建集合上的操作,该集合包含一个索引字段,其相应的索引条目超过限制,但在日志中带有警告。
  • 混合版本副本集中,次要版本2.6,主版本是2.4,次要版本将复制在2.4主版本上插入或更新的文档,但如果文档包含相应索引条目超过限制的索引字段,则会在日志中打印错误消息。
解决方案

​ 运行db.upgradeCheckAllDBs()查找违反此限制的当前密钥并进行适当的更正。最好在升级之 前运行测试;例如,将2.6 mongo shell连接到MongoDB2.4数据库并运行该方法。

如果您有现有的数据集,并且希望禁用默认索引键长度验证,以便在解决这些索引问题之前可以进行升级,请使用 failIndexKeyTooLong 参数。

索引规范验证字段名称

描述

在MongoDB 2.6中,当indexkey引用空字段时,创建和重新索引操作失败,例如"a..b" : 1或字段名称以美元符号($)开头。

以前版本的MongoDB允许索引。

解决方案

​ 运行 db.upgradeCheckAllDBs()查找违反此限制的当前密钥并进行适当的更正。最好在升级之 前运行测试;例如,将2.6 mongo shell连接到MongoDB2.4数据库并运行该方法。

ensureIndex和现有指数

描述

db.collection.ensureIndex()现在错误:

  • 如果您尝试创建现有索引,但选项不同;例如,在以下示例中,stdbdb.collection.ensureIndex()将出错。

    db.mycollection.ensureIndex( { x: 1 } )
    db.mycollection.ensureIndex( { x: 1 }, { unique: 1 } )
    
  • 如果您指定了一个已经存在的索引名称,但键规格不同;例如,在以下示例中,stdbdb.collection.ensureIndex()将出错。

    db.mycollection.ensureIndex( { x: 1 } )
    db.mycollection.ensureIndex( { x: 1 }, { unique: 1 } )
    

    以前的版本没有创建索引,但没有出错。

写入方法确认

描述

mongo shell写方法db.collection.insert()db.collection.update()、db.collection.save()和 db.collection.remove()现在将写关注点直接集成到方法中,而不是使用单独的getLastError命令来提供确认写入,无论是在mongo shell中交互运行还是在脚本中非交互运行。在以前的版本中,这些方法表现出一种"触发并忘记"的行为。[1]

  • 使用这些方法的mongo shell的现有脚本现在将等待确认,这比以前的“即发即忘”行为花费更长的时间。
  • write方法现在返回一个WriteResult()对象 包含操作的结果,包括任何写入错误 和写入关注错误,并避免了调用 getLastError命令获取结果的状态。 参见db.collection.insert()db.collection.update()db.collection.save()db.collection.remove()获取详细信息。
  • 在碎片化环境中,Mongo不再支持 “开火就忘”的行为。这会限制写入数据时的吞吐量 到碎片簇。
[1] 在以前的版本中,使用 mongo 壳 交互地, mongo shell自动调用 getLastError 命令,以提供 写入的确认。然而,脚本将遵守“发射和遗忘” 以前版本中的行为,除非脚本包含 外显 调用 getLastError 命令之后 写入方法。
解决方案

使用这些mongo shell方法进行批量写入的脚本 具有“触发并忽略”行为的操作应使用 Bulk()方法。

在分片环境中,使用任何驱动程序或 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 } );

Bulk方法返回包含以下内容的BulkWriteResult()对象 操作的结果。

另见:

数据库集合聚合()更改

说明

mongoshell中的 db.collection.aggregate()方法默认将游标返回到结果设置。此更改使聚合管道能够返回结果 任何大小的集合,并且需要游标迭代才能访问结果 设置。例如:

var myCursor = db.orders.aggregate( [
    {
      $group: {
         _id: "$cust_id",
         total: { $sum: "$price" }
      }
    }
] );

myCursor.forEach( function(x) { printjson (x); } );

以前的版本返回了一个带有字段results文档,其中包含结果集的数组,但受BSONDocument大小限制。访问之前版本的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); } );
解决方案

更新目前期望db.collection.aggregate()返回带有results数组的文档以处理光标的脚本。

另见:

写入问题验证

描述

指定包含以下内容的写入关注 j: true 到一个 mongodmongos 实例运行 --nojournal 选项现在错误。以前的版本将 忽略 j: true

解决方案

或者移除 j: true 写入关注点的规范,当 开据 mongodmongos 实例 与 --nojournal 或运行 mongodmongos 写日记。

安全变更

新的授权模式

描述

MongoDB 2.6授权模型改变了MongoDB存储和管理用户特权信息的方式:

  • 在升级之前,MongoDB 2.6在管理数据库中至少需要一个用户。

  • 使用旧模型的MongoDB版本无法创建/修改用户或创建用户定义的角色。

解决方案

确保管理数据库中至少存在一个用户。如果管理数据库中不存在用户,请添加用户。然后升级到MongoDB 2.6。最后,升级用户权限模型。请参阅将MongoDB升级到2.6。

重要:

在升级授权模型之前,您应该首先将MongoDB二进制文件升级到2.6。对于分片集群,请确保所有集群组件均为2.6。如果任何数据库中有用户,请确保在升级MongoDBbinaries之前,使用角色userAdminAnyDatabaseadmin数据库中至少有一个用户。

另见:

安全改进

SSL证书主机名验证

描述

SSL证书验证现在检查通用名称(CN)和主题替代名称(SAN)字段,以确保CNSAN条目之一与服务器的主机名匹配。因此,如果您当前使用SSL,并且当前SSL证书的CN

解决方案

为了允许继续使用这些证书,MongoDB提供了allowInvalidCertificates设置。该设置适用于:

  • mongodmongos绕过集群中其他服务器上SSL证书的验证。
  • mongoshell、支持SSL的MongoDB工具和绕过服务器证书验证的C++驱动程序。

当使用allowInvalidCertificates设置时,MongoDB 将使用无效证书的情况记录为警告。

警告:

allowInvalidCertificates设置绕过其他证书验证,例如检查过期和有效签名。

2dsphere索引版本2

描述

MongoDB 2.6引入了2dsphere索引的第2版。如果文档缺少2dsphere索引字段(或字段为空数组),MongoDB不会将文档的条目添加到2dsphere索引中。对于插入,MongoDB插入文档,但不添加到2dsphere索引中。

之前的版本不会插入2dsphere字段为null或空数组的文档。对于缺少2dsphere索引字段的文档,以前的版本将插入和索引文档。

解决方案

要恢复到旧行为,请使用{ "2dsphereIndexVersion" : 1 }创建2dsphere索引以创建版本1索引。然而,版本1索引不能使用新的GeoJSON几何形状。

另见:

版本

日志消息

时间戳格式更改

描述

现在,每条消息都以时间格式更改。以前的版本使用ctime格式。

解决方案

MongoDB添加了一个新的选项--timeStampFormat,该选项支持ctimeiso8601-utciso8601-local(新默认值)中的timestamp格式。

软件包配置更改

RPM/DEB软件包的默认bindIp

描述

在RPM(红帽、CentOS、FedoraLinux和衍生品)和DEB(Debian、Ubuntu和衍生品)中的官方MongoDB软件包中,默认bindIp将MongoDB组件附加到本地主机接口。这些软件包在默认配置文件(即/etc/mongod.conf.)中设置了此默认值。

解决方案

如果您使用这些软件包之一,并且没有修改default/etc/mongod.conf文件,则需要在升级之前或升级期间设置bindIp

在任何其他官方的MongoDBpackages中都没有默认的bindIp设置。

SNMP更改

描述
  • MongoDB的IANA企业标识符从37601更改为34601。

  • MongoDB将MIB字段名称globalopcounts更改为globalOpcounts

解决方案
  • SNMP监控的用户必须修改他们的SNMP配置(即MIB)从37601到34601。

  • globalopcounts引用更新为globalOpcounts

删除方法签名更改

描述

​ db.collection.remove()需要查询文档作为参数。在之前的版本中,没有查询文档的方法调用删除了集合中的所有文档。

解决方案

​ 对于没有查询文档的现有db.collection.remove()调用,请修改调用以包含空documentdbdb.collection.remove()

更新运算符语法验证

描述

更新强制执行字段名称限制

描述

更新不能使用更新运算符(例如$set)来目标字段名称为空的字段(即""。更新不再支持保存包含点(.)或以美元符号($)开头的字段名的字段名。

解决方案

对于具有空名称为""的字段的现有文档,请替换整个文档。有关替换现有文档的详细信息,请参阅db.collection.update()db.collection.save()。对于具有名称包含点(.)的字段的现有文档,请替换整个文档或unset字段。要查找名称包含点的字段,请运行db.upgradeCheckAllDBs()。对于名称以美元符号($)开头的字段的现有文档,请unsetrename这些字段。要查找名称以美元符号开头的字段,请运行db.upgradeCheckAllDBs()。

有关写入操作协议的更改,请参阅新写入操作协议,有关插入更新操作的更改,请参阅插入更新改进。另请考虑字段名称限制的文档

查询和排序更改

执行字段名称限制

描述

查询无法在名称以美元符号($)开头的字段上指定条件。

解决方案

Unsetrename名称以美元符号($)开头的现有字段。跑步db.upgradeCheckAllDBs()查找名称以美元符号开头的字段。

稀疏的索引和不完整的结果

描述

如果稀疏索引导致查询和排序操作的结果集不完整,除非hint()明确指定索引,否则MongoDB不会使用该索引。例如,除非明确提示,否则查询{ x: { $exists: false } }将不再在x字段上使用稀疏索引。

解决方案

要覆盖使用稀疏索引的行为并返回不完整结果,请用hint()显式指定索引

有关详细说明新行为的示例,请参阅集合上的稀疏索引无法返回完整结果

sort()规格值

描述

sort()方法接受排序键的以下值:

  • 1指定字段的升序,
  • -1指定字段的降序,或
  • $meta表达式,按文本搜索分数指定排序。

任何其他值都将导致错误。

以前的版本也接受truefalse提升。

解决方案

将使用truefalse的排序键值更新为1。

skip()_id查询

描述

_id字段上的平等匹配服从skip()以前的版本在_id字段上执行相等匹配时忽略了skip()

explain()保留查询计划缓存

描述

explain()不再清除缓存为该查询形状的查询计划

在之前的版本中,explain()将产生清除该查询形状的查询计划缓存的副作用。

另见:

PlanCache()参考。

地理空间变化

$maxDistance变化
描述

对于GeoJSON数据的$near查询,如果查询指定a$maxDistance$maxDistance必须在$near文档中。在之前的版本中,$maxDistance可以在$near文档的内部或外部。$maxDistance必须是一个积极的价值。

解决方案

更新GeoJSON数据上任何现有的$near,这些查询目前在$near文档之外具有$maxDistance更新$maxDistance为负值的任何现有查询。

不建议使用的$uniqueDocs
描述

MongoDB 2.6不建议使用$uniqueDocs,当文档多次匹配查询时,地理空间查询不再返回重复的结果。

更有力地验证地理空间查询
描述

MongoDB 2.6强制对地理空间查询进行更强的验证,例如验证选项或GeoJSON规范,如果地理空间查询无效,则设置错误。以前的版本允许/忽略无效选项。

查询运算符更改

$not查询行为变更
描述
  • 索引字段上带有$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表达式。

null比较查询
描述
  • $lt$gtnull的比较不再匹配缺少字段的文档。
  • null数组元素上的相等条件(例如"a.b": null)不再匹配缺少嵌套字段a.b的文档(例如a: [ 2, 3 ])。
  • null平等查询(即field: null)现在将字段与undefined的值匹配。
$all操作员行为变更
描述
  • $all运算符现在等价于指定值的$and运算。当传递单个嵌套数组的数组时,这种行为变化可以允许比以前的版本更多的匹配(例如[ [ "A" ] ])。当传递嵌套数组的数组时,$all现在可以匹配字段包含嵌套数组作为元素的文档(例如field: [ [ "A" ], ... ]),或者该字段等于嵌套数组(例如field: [ "A", "B" ])。早期版本只能匹配字段包含嵌套数组的文档。
  • 如果数组字段包含嵌套数组(例如field: [ "a", ["b"] ]),并且嵌套字段上的$all是嵌套数组的元素(例如.""field.1": { $all: [ "b" ] }),则$all运算符不返回匹配项。以前的版本将返回匹配项。
$mod运算符执行严格的语法
描述

$mod运算符现在只接受一个正好有两个元素的数组,当传递元素较少或更多元素的数组时会出现错误。有关详细信息,请参阅元素不足错误元素太多错误

在之前的版本中,如果传递了一个带有一个元素的数组,$mod运算符使用0作为第二个元素,如果传递了一个包含两个以上元素的数组,$mod会忽略除前两个元素以外的所有元素。以前的版本在传递空数组时确实会返回错误。

解决方案

确保传递给$mod的数组恰好包含两个元素:

  • 如果数组包含单个元素,请添加0作为第二个元素。
  • 如果数组包含两个以上的元素,请删除外部元素。
$where必须是顶级的
描述

$where表达式现在只能处于顶层,不能在另一个表达式中音调,例如$elemMatch

解决方案

更新嵌套$where的现有查询

$existsnotablescan

如果MongoDB服务器禁用了集合扫描,即notablescan,那么没有索引解决方案$exists查询将出错。

MinKeyMaxKey查询
描述

MinKeyMaxKey的平等匹配不再匹配缺少字段的文档。

使用$elemMatch嵌套数组查询
描述

$elemMatch查询运算符不再递归遍历到嵌套数组中。

例如,如果集合test包含以下文档:

{ "_id": 1, "a" : [ [ 1, 2, 5 ] ] }

在2.6中,以下$elemMatch查询与文档匹配:

db.test.find( { a: { $elemMatch: { $gt: 1, $lt: 5 } } } )
解决方案

更新依赖于旧行为的现有查询。

文本搜索兼容性

MongoDB不支持在包含2.4和2.6版本碎片的混合分片集群部署中使用$text查询运算符。有关升级说明,请参阅将MongoDB升级到2.6

复制集/共享集群验证

元数据刷新上的碎片名称检查

描述

对于分片集群,如果碎片名称尚未显式设置,MongoDB 2.6不允许碎片刷新元数据。

对于同时包含2.4版和2.6版碎片的混合碎片集群部署,如果2.6版本碎片名称未知,则此更改可能会在将块2.4版本碎片迁移2.6碎片时导致错误。MongoDB不支持混合分片集群部署中的迁移。

解决方案

将集群的所有组件升级到2.6。请参阅将MongoDB升级到2.6。

副本集投票配置验证

描述

MongoDB现在不建议给任何复制集成员超过一票。在配置期间,members[n\].votes对于有投票权的成员,对于无表决权的成员,该值应为0。MongoDB将1或0以外的值视为1的值,并生成警告消息。

解决方案

酌情更新members[n\].votes值为1或0至1或0以外的值。

时间格式更改

MongoDB现在在许多输出中格式化时间数据时使用iso8601-local。此格式遵循模板YYYY-MM-DDTHH:mm:ss.mmm<+/-Offset>。例如,2014-03-04T20:13:38.944-0500

此更改会影响在严格模式下使用扩展JSON的所有客户端,例如mongoexport

其他资源

参见

原文 - Compatibility Changes in MongoDB 2.6

Copyright © 上海锦木信息技术有限公司 all right reserved,powered by Gitbook文件修订时间: 2023-09-01 17:10:26

results matching ""

    No results matching ""