OPTIONS
翻译或纠错本页面

Compatibility Changes in MongoDB 2.6

The following 2.6 changes can affect the compatibility with older versions of MongoDB. See Release Notes for MongoDB 2.6 for the full list of the 2.6 changes.

Index Changes

Enforce Index Key Length Limit

Description

MongoDB 2.6 implements a stronger enforcement of the limit on index key.

Creating indexes will error if an index key in an existing document exceeds the limit:

Inserts will error:

  • db.collection.insert() and other operations that perform inserts (e.g. db.collection.save() and db.collection.update() with upsert that result in inserts) will fail to insert if the new document has an indexed field whose corresponding index entry exceeds the limit. Previous versions of MongoDB would insert but not index such documents.
  • mongorestore and mongoimport will fail to insert if the new document has an indexed field whose corresponding index entry exceeds the limit.

Updates will error:

  • db.collection.update() and db.collection.save() operations on an indexed field will error if the updated value causes the index entry to exceed the limit.
  • If an existing document contains an indexed field whose index entry exceeds the limit, updates on other fields that result in the relocation of a document on disk will error.

Chunk Migration will fail:

  • Migrations will fail for a chunk that has a document with an indexed field whose index entry exceeds the limit.
  • If left unfixed, the chunk will repeatedly fail migration, effectively ceasing chunk balancing for that collection. Or, if chunk splits occur in response to the migration failures, this response would lead to unnecessarily large number of chunks and an overly large config databases.

Secondary members of replica sets will warn:

  • Secondaries will continue to replicate documents with an indexed field whose corresponding index entry exceeds the limit on initial sync but will print warnings in the logs.
  • Secondaries allow index build and rebuild operations on a collection that contains an indexed field whose corresponding index entry exceeds the limit but with warnings in the logs.
  • With mixed version replica sets where the secondaries are version 2.6 and the primary is version 2.4, secondaries will replicate documents inserted or updated on the 2.4 primary, but will print error messages in the log if the documents contain an indexed field whose corresponding index entry exceeds the limit.
Solution
Run db.upgradeCheckAllDBs() to find current keys that violate this limit and correct as appropriate. Preferably, run the test before upgrading; i.e. connect the 2.6 mongo shell to your MongoDB 2.4 database and run the method.

If you have an existing data set and want to disable the default index key length validation so that you can upgrade before resolving these indexing issues, use the failIndexKeyTooLong parameter.

Index Specifications Validate Field Names

Description

In MongoDB 2.6, create and re-index operations fail when the index key refers to an empty field, e.g. "a..b" : 1 or the field name starts with a dollar sign ($).

Previous versions of MongoDB allow the index.

Solution
Run db.upgradeCheckAllDBs() to find current keys that violate this limit and correct as appropriate. Preferably, run the test before upgrading; i.e. connect the 2.6 mongo shell to your MongoDB 2.4 database and run the method.

ensureIndex and Existing Indexes

Description

db.collection.ensureIndex() now errors:

  • if you try to create an existing index but with different options; e.g. in the following example, the second db.collection.ensureIndex() will error.

    db.mycollection.ensureIndex( { x: 1 } )
    db.mycollection.ensureIndex( { x: 1 }, { unique: 1 } )
    
  • if you specify an index name that already exists but the key specifications differ; e.g. in the following example, the second db.collection.ensureIndex() will error.

    db.mycollection.ensureIndex( { a: 1 }, { name: "myIdx" } )
    db.mycollection.ensureIndex( { z: 1 }, { name: "myIdx" } )
    

Previous versions did not create the index but did not error.

Write Method Acknowledgements

Description
The mongo shell write methods db.collection.insert(), db.collection.update(), db.collection.save() and db.collection.remove() now integrate the write concern directly into the method rather than with a separate getLastError command to provide safe writes whether run interactively in the mongo shell or non-interactively in a script. In previous versions, these methods exhibited a “fire-and-forget” behavior. [1]
  • Existing scripts for the mongo shell that used these methods will now observe safe writes which take longer than the previous “fire-and-forget” behavior.
  • The write methods now return a WriteResult object that contains the results of the operation, including any write errors and write concern errors, and obviates the need to call getLastError command to get the status of the results. See db.collection.insert(), db.collection.update(), db.collection.save() and db.collection.remove() for details.
  • In sharded environments, mongos no longer supports “fire-and-forget” behavior. This limits throughput when writing data to sharded clusters.
[1]In previous versions, when using the mongo shell interactively, the mongo shell automatically called the getLastError command after a write method to provide “safe writes”. Scripts, however, would observe “fire-and-forget” behavior in previous versions unless the scripts included an explicit call to the getLastError command after a write method.
Solution

Scripts that used these mongo shell methods for bulk write operations with “fire-and-forget” behavior should use the Bulk() methods.

In sharded environments, applications using any driver or mongo shell should use Bulk() methods for optimal performance when inserting or modifying groups of documents.

For example, instead of:

for (var i = 1; i <= 1000000; i++) {
    db.test.insert( { x : i } );
}

In MongoDB 2.6, replace with Bulk() operation:

var bulk = db.test.initializeUnorderedBulkOp();

for (var i = 1; i <= 1000000; i++) {
    bulk.insert( { x : i} );
}

bulk.execute( { w: 1 } );

Bulk method returns a BulkWriteResult object that contains the result of the operation.

db.collection.aggregate() Change

Description

The db.collection.aggregate() method in the mongo shell defaults to returning a cursor to the results set. This change enables the aggregation pipeline to return result sets of any size and requires cursor iteration to access the result set. For example:

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

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

Previous versions returned a single document with a field results that contained an array of the result set, subject to the BSON Document size limit. Accessing the result set in the previous versions of MongoDB required accessing the results field and iterating the array. For example:

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
Update scripts that currently expect db.collection.aggregate() to return a document with a results array to handle cursors instead.

Write Concern Validation

Description
Specifying a write concern that includes j: true to a mongod or mongos instance running with --nojournal option now errors. Previous versions would ignore the j: true.
Solution
Either remove the j: true specification from the write concern when issued against a mongod or mongos instance with --nojournal or run mongod or mongos with journaling.

Security Changes

New Authorization Model

Description

MongoDB 2.6 authorization model changes how MongoDB stores and manages user privilege information:

  • Before the upgrade, MongoDB 2.6 requires at least one user in the admin database.
  • MongoDB versions using older models cannot create/modify users or create user-defined roles.
Solution

Ensure that at least one user exists in the admin database. If no user exists in the admin database, add a user. Then upgrade to MongoDB 2.6. Finally, upgrade the user privilege model. See Upgrade MongoDB to 2.6.

重要

Before upgrading the authorization model, you should first upgrade MongoDB binaries to 2.6. For sharded clusters, ensure that all cluster components are 2.6. If there are users in any database, be sure you have at least one user in the admin database before upgrading the MongoDB binaries.

SSL Certificate Hostname Validation

Description
The SSL certificate validation now checks the Common Name (CN) and the Subject Alternative Name (SAN) fields to ensure that either the CN or one of the SAN entries matches the hostname of the server. As a result, if you currently use SSL and neither the CN nor any of the SAN entries of your current SSL certificates match the hostnames, upgrading to version 2.6 will cause the SSL connections to fail.
Solution

To allow for the continued use of these certificates, MongoDB provides the allowInvalidCertificates setting. The setting is available for:

When using the allowInvalidCertificates setting, MongoDB logs as a warning the use of the invalid certificates.

警告

The allowInvalidCertificates setting bypasses the other certificate validation, such as checks for expiration and valid signatures.

2dsphere Index Version 2

Description

MongoDB 2.6 introduces a version 2 of the 2dsphere index. If a document lacks a 2dsphere index field (or the field is null or an empty array), MongoDB does not add an entry for the document to the 2dsphere index. For inserts, MongoDB inserts the document but does not add to the 2dsphere index.

Previous version would not insert documents where the 2dsphere index field is a null or an empty array. For documents that lack the 2dsphere index field, previous versions would insert and index the document.

Solution
To revert to old behavior, create the 2dsphere index with { "2dsphereIndexVersion" : 1 } to create a version 1 index. However, version 1 index cannot use the new GeoJSON geometries.

Log Messages

Timestamp Format Change

Description
Each message now starts with the timestamp formatted in iso8601-local, i.e. YYYY-MM-DDTHH:mm:ss.mmm<+/-Offset>. For example, 2014-03-04T20:13:38.944-0500. Previous versions used ctime format.
Solution
MongoDB adds a new option --timeStampFormat which supports timestamp format in ctime, iso8601-utc, and iso8601-local (new default).

Package Configuration Changes

Default bindIp for RPM/DEB Packages

Description
In the official MongoDB packages in RPM (Red Hat, CentOS, Fedora Linux, and derivatives) and DEB (Debian, Ubuntu, and derivatives), the default bindIp value attaches MongoDB components to the localhost interface only. These packages set this default in the default configuration file (i.e. /etc/mongodb.conf.)
Solution
If you use one of these packages and have not modified the default /etc/mongodb.conf file, you will need to set bindIp before or during the upgrade.

There is no default bindIp setting in any other official MongoDB packages.

SNMP Changes

Description
  • The IANA enterprise identifier for MongoDB changed from 37601 to 34601.
  • MongoDB changed the MIB field name globalopcounts to globalOpcounts.
Solution
  • Users of SNMP monitoring must modify their SNMP configuration (i.e. MIB) from 37601 to 34601.
  • Update references to globalopcounts to globalOpcounts.

Remove Method Signature Change

Description
db.collection.remove() requires a query document as a parameter. In previous versions, the method invocation without a query document deleted all documents in a collection.
Solution
For existing db.collection.remove() invocations without a query document, modify the invocations to include an empty document db.collection.remove({}).

Update Operator Syntax Validation

Description
  • Update operators (e.g $set) must specify a non-empty operand expression. For example, the following expression is now invalid:

    { $set: { } }
    
  • Update operators (e.g $set) cannot repeat in the update statement. For example, the following expression is invalid:

    { $set: { a: 5 }, $set: { b: 5 } }
    

Updates Enforce Field Name Restrictions

Description
  • Updates cannot use update operators (e.g $set) to target fields with empty field names (i.e. "").
  • Updates no longer support saving field names that contain a dot (.) or a field name that starts with a dollar sign ($).
Solution
  • For existing documents that currently have fields with empty names "", replace the whole document. See db.collection.update() and db.collection.save() for details on replacing an existing document.
  • Unset or rename existing fields with names that contain a dot (.) or that start with a dollar sign ($). Run db.upgradeCheckAllDBs() to find fields whose names contain a dot or starts with a dollar sign.

See New Write Operation Protocol for the changes to the write operation protocol, and Insert and Update Improvements for the changes to the insert and update operations. Also consider the documentation of the Restrictions on Field Names.

Query and Sort Changes

Enforce Field Name Restrictions

Description
Queries cannot specify conditions on fields with names that start with a dollar sign ($).
Solution
Unset or rename existing fields whose names start with a dollar sign ($). Run db.upgradeCheckAllDBs() to find fields whose names start with a dollar sign.

Sparse Index and Incomplete Results

Description

If a sparse index results in an incomplete result set for queries and sort operations, MongoDB will not use that index unless a hint() explicitly specifies the index.

For example, the query { x: { $exists: false } } will no longer use a sparse index on the x field, unless explicitly hinted.

Solution
To override the behavior to use the sparse index and return incomplete results, explicitly specify the index with a hint().

See 在A集合上的稀疏索引不会返回完整结果 for an example that details the new behavior.

sort() Specification Values

Description

The sort() method only accepts the following values for the sort keys:

  • 1 to specify ascending order for a field,
  • -1 to specify descending order for a field, or
  • $meta expression to specify sort by the text search score.

Any other value will result in an error.

Previous versions also accepted either true or false for ascending.

Solution
Update sort key values that use true or false to 1.

skip() and _id Queries

Description

Equality match on the _id field obeys skip().

Previous versions ignored skip() when performing an equality match on the _id field.

explain() Retains Query Plan Cache

Description

explain() no longer clears the query plans cached for that query shape.

In previous versions, explain() would have the side effect of clearing the query plan cache for that query shape.

Geospatial Changes

$maxDistance Changes

Description
Solution
  • Update any existing $near queries on GeoJSON data that currently have the $maxDistance outside the $near document
  • Update any existing queries where $maxDistance is a negative value.

Deprecated $uniqueDocs

Description
MongoDB 2.6 deprecates $uniqueDocs, and geospatial queries no longer return duplicated results when a document matches the query multiple times.

Stronger Validation of Geospatial Queries

Description
MongoDB 2.6 enforces a stronger validation of geospatial queries, such as validating the options or GeoJSON specifications, and errors if the geospatial query is invalid. Previous versions allowed/ignored invalid options.

Query Operator Changes

$not Query Behavior Changes

Description
  • Queries with $not expressions on an indexed field now match:

    • Documents that are missing the indexed field. Previous versions would not return these documents using the index.
    • Documents whose indexed field value is a different type than that of the specified value. Previous versions would not return these documents using the index.

    For example, if a collection orders contains the following documents:

    { _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" }
    

    If the collection has an index on the price field:

    db.orders.ensureIndex( { price: 1 } )
    

    The following query uses the index to search for documents where price is not greater than or equal to 50:

    db.orders.find( { price: { $not: { $gte: 50 } } } )
    

    In 2.6, the query returns the following documents:

    { "_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" }
    

    In previous versions, indexed plans would only return matching documents where the type of the field matches the type of the query predicate:

    { "_id" : 1, "status" : "A", "cust_id" : "123", "price" : 40 }
    

    If using a collection scan, previous versions would return the same results as those in 2.6.

  • MongoDB 2.6 allows chaining of $not expressions.

null Comparison Queries

Description
  • $lt and $gt comparisons to null no longer match documents that are missing the field.
  • null equality conditions on array elements (e.g. "a.b": null) no longer match document missing the nested field a.b (e.g. a: [ 2, 3 ]).
  • null equality queries (i.e. field: null ) now match fields with values undefined.

$all Operator Behavior Change

Description
  • The $all operator is now equivalent to an $and operation of the specified values. This change in behavior can allow for more matches than previous versions when passed an array of a single nested array (e.g. [ [ "A" ] ]). When passed an array of a nested array, $all can now match documents where the field contains the nested array as an element (e.g. field: [ [ "A" ], ... ]), or the field equals the nested array (e.g. field: [ "A", "B" ]). Earlier version could only match documents where the field contains the nested array.
  • The $all operator returns no match if the array field contains nested arrays (e.g. field: [ "a", ["b"] ]) and $all on the nested field is the element of the nested array (e.g. "field.1": { $all: [ "b" ] }). Previous versions would return a match.

$mod Operator Enforces Strict Syntax

Description

The $mod operator now only accepts an array with exactly two elements, and errors when passed an array with fewer or more elements. See Not Enough Elements Error and Too Many Elements Error for details.

In previous versions, if passed an array with one element, the $mod operator uses 0 as the second element, and if passed an array with more than two elements, the $mod ignores all but the first two elements. Previous versions do return an error when passed an empty array.

Solution

Ensure that the array passed to $mod contains exactly two elements:

  • If the array contains the a single element, add 0 as the second element.
  • If the array contains more than two elements, remove the extra elements.

$where Must Be Top-Level

Description
$where expressions can now only be at top level and cannot be nested within another expression, such as $elemMatch.
Solution
Update existing queries that nest $where.

$exists and notablescan

If the MongoDB server has disabled collection scans, i.e. notablescan, then $exists queries that have no indexed solution will error.

MinKey and MaxKey Queries

Description
Equality match for either MinKey or MaxKey no longer match documents missing the field.

Nested Array Queries with $elemMatch

Description

The $elemMatch query operator no longer traverses recursively into nested arrays.

For example, if a collection test contains the following document:

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

In 2.6, the following $elemMatch query does not match the document:

db.test.find( { a: { $elemMatch: { $gt: 1, $lt: 5 } } } )
Solution
Update existing queries that rely upon the old behavior.

Text Search Compatibility

MongoDB does not support the use of the $text query operator in mixed sharded cluster deployments that contain both version 2.4 and version 2.6 shards. See Upgrade MongoDB to 2.6 for upgrade instructions.

Replica Set/Sharded Cluster Validation

Shard Name Checks on Metadata Refresh

Description

For sharded clusters, MongoDB 2.6 disallows a shard from refreshing the metadata if the shard name has not been explicitly set.

For mixed sharded cluster deployments that contain both version 2.4 and version 2.6 shards, this change can cause errors when migrating chunks from version 2.4 shards to version 2.6 shards if the shard name is unknown to the version 2.6 shards. MongoDB does not support migrations in mixed sharded cluster deployments.

Solution
Upgrade all components of the cluster to 2.6. See Upgrade MongoDB to 2.6.

Replica Set Vote Configuration Validation

Description
MongoDB now deprecates giving any replica set member more than a single vote. During configuration, local.system.replset.members[n].votes should only have a value of 1 for voting members and 0 for non-voting members. MongoDB treats values other than 1 or 0 as a value of 1 and produces a warning message.
Solution
Update local.system.replset.members[n].votes with values other than 1 or 0 to 1 or 0 as appropriate.