Navigation

Compatibility Changes in MongoDB 3.6

The following 3.6 changes can affect the compatibility with older versions of MongoDB.

Localhost Binding Compatibility Changes

Starting in MongoDB 3.6, MongoDB binaries, mongod and mongos, bind to localhost by default. If the net.ipv6 configuration file setting or the --ipv6 command line option is set for the binary, the binary additionally binds to the localhost IPv6 address.

Previously, starting from MongoDB 2.6, only the binaries from the official MongoDB RPM (Red Hat, CentOS, Fedora Linux, and derivatives) and DEB (Debian, Ubuntu, and derivatives) packages bind to localhost by default.

When bound only to the localhost, these MongoDB 3.6 binaries can only accept connections from clients (including the mongo shell, other members in your deployment for replica sets and sharded clusters) that are running on the same machine. Remote clients cannot connect to the binaries bound only to localhost.

To override and bind to other ip addresses, you can use the net.bindIp configuration file setting or the --bind_ip command-line option to specify a list of hostnames or ip addresses.

Warning

Before binding to a non-localhost (e.g. publicly accessible) IP address, ensure you have secured your cluster from unauthorized access. For a complete list of security recommendations, see Security Checklist. At minimum, consider enabling authentication and hardening network infrastructure.

For example, the following mongod instance binds to both the localhost and the hostname My-Example-Associated-Hostname, which is associated with the ip address 198.51.100.1:

mongod --bind_ip localhost,My-Example-Associated-Hostname

In order to connect to this instance, remote clients must specify the hostname or its associated ip address 198.51.100.1:

mongo --host My-Example-Associated-Hostname

mongo --host 198.51.100.1

To bind to all IPv4 addresses, you can specify the bind ip address of 0.0.0.0. To bind to all IPv4 and IPv6 addresses, you can specify the bind ip address of ::,0.0.0.0 or alternatively, use the new net.bindIpAll setting or the new command-line option --bind_ip_all.

Shard Replica Set

Starting in 3.6, shards must be replica sets. To upgrade your sharded cluster to version 3.6, the shard servers must be running as a replica set.

To convert an existing shard standalone instance to a shard replica set, see Convert a Shard Standalone to a Shard Replica Set.

HTTP Interface and REST API

MongoDB 3.6 removes the deprecated HTTP interface and REST API to MongoDB.

Configuration Settings mongod/mongos option
net.http.enabled
net.http.JSONPEnabled
net.http.port
net.http.RESTInterfaceEnabled
httpinterface
nohttpinterface
jsonp
rest

Tools Changes

MongoDB 3.6 removes the deprecated mongooplog tool.

Array Operation Compatibility Changes

$type: "array" Behavior Change

Starting in 3.6, $type: "array" and $type: 4 expressions match array fields that contain any element type.

In earlier versions, $type : "array" only matches array fields that contain nested arrays.

For example, a collection named c contains two documents:

{ "_id": 1, "a": [ 1, 2, 3 ] },
{ "_id": 2, "a": [ 1, 2, [ 3, 4 ] ] }

The following operation queries by type on field a:

db.c.find( { "a": { $type : "array" } } )

Starting in 3.6, the query returns both documents in the collection because the $type query can now detect that field a is itself an array.

{ "_id": 1, "a": [ 1, 2, 3 ] },
{ "_id": 2, "a": [ 1, 2, [ 3, 4 ] ] }

In 3.4 and earlier versions of MongoDB, the query only returns those documents in which the array field a contains an element of BSON type array.

{ "_id": 2, "a": [ 1, 2, [ 3, 4 ] ] }

If upgrading from a MongoDB 3.4.x deployment that has partial indexes whose partialFilterExpression includes a $type : "array" or $type : 4 expression, you must rebuild these indexes after upgrading to avoid conflicting $type : 'array' semantics.

For more information on the $type: "array" expression, see Querying by Array Type.

Array Sort Behavior

Starting in 3.6, when sorting a field containing an array, MongoDB orders the field with the lowest-valued element of the array first for ascending sorts and the highest-valued element of the array first for descending sorts. A sort no longer takes the query predicate into account when choosing the array element which will act as the sort key. This behavior change applies to both the find command and the aggregation pipeline.

As a result of this change, applications that currently sort by an array field may experience a different sort order.

Important

As a result of changes to sorting behavior on array fields in MongoDB 3.6, when sorting on an array indexed with a multikey index the query plan includes a blocking SORT stage. The new sorting behavior may negatively impact performance.

In a blocking SORT, all input must be consumed by the sort step before it can produce output. In a non-blocking, or indexed sort, the sort step scans the index to produce results in the requested order.

find Method Sorting

A sort key is the array element MongoDB uses during the sorting process to compare and ultimately order documents containing an array. In an ascending sort, documents containing arrays with the lowest-valued sort keys are ordered first. Likewise, in a descending sort, documents containing arrays with the highest-valued sort keys are ordered first.

In MongoDB 3.4 and earlier, a sort by an array field took into account the query predicate when determining the sort key.

For example, a collection coll has the following documents:

{ _id: 0, a: [-3, -2, 2, 3] }
{ _id: 1, a: [ 5, -4 ] }

Consider following sort operation on the array field a of the collection:

db.coll.find({a: {$gte: 0}}).sort({a: 1});

In MongoDB 3.6, the sort operation no longer takes into account the query predicate when determining its sort key. As a result, the sort key is the lowest-valued element for each document:

  • -3 for the document with _id: 0 and
  • -4 for the document with _id: 1.

The operation returns the documents in the following order:

{ "_id" : 1, "a" : [ 5, -4 ] }
{ "_id" : 0, "a" : [ -3, -2, 2, 3 ] }

Previous MongoDB versions use the lowest-valued array element that matches the query predicate of {$gte: 0} as the sort key:

  • 2 for the document with _id: 0 and
  • 5 for the document with _id: 1,

and would return the documents in the following order:

{ _id: 0, a: [-3, -2, 2, 3] }
{ _id: 1, a: [ 5, -4 ] }

aggregate Method Sorting

In MongoDB 3.6, when sorting array fields with the db.collection.aggregate() method, only a single array element is used as the sort key.

Consider the following example:

// Documents.
{ "_id" : 1, "timestamps" : [ ISODate("2017-07-15T15:31:01Z"), ISODate("2017-07-21T18:31:01Z") ] }
{ "_id" : 0, "timestamps" : [ ISODate("2017-07-21T15:31:01Z"), ISODate("2017-07-21T13:31:01Z") ] }

// Query.
db.c.aggregate([{$sort: {timestamps: -1}}])

For a descending sort, the most recent time in the array is used as the sort key: 3:31 PM on July 21 for the document with _id: 0 and 5:31 PM on July 21 for the document with _id: 1. Since the sort is descending, these keys are then ordered from most recent to least recent, resulting in the document with _id: 1 sorting before the document with _id: 0.

Before 3.6, the entire array is used as the sort key for aggregation sorts. The array sort keys are compared element-wise to determine the sort order of the result set.

Example

// Documents.
{_id: 0, a: [3, 1, 5]}
{_id: 1, a: [3, 4, 0]}

// Query.
db.coll.aggregate([{$sort: {a: 1}}])

Prior to 3.6, the sort keys are [3, 1, 5] and [3, 4, 0] respectively. Since the first array elements are equal, the second array element breaks the tie and the document with _id: 0 sorts first.

For more information on sorting with the Aggregation Pipeline, see $sort.

Sorting with a Compound Sort Pattern on Multiple Array Fields with aggregate

In MongoDB 3.6, when sorting in an aggregation pipeline, MongoDB can no longer sort documents which contain parallel arrays in the fields being sorted on. Arrays are considered parallel if they are sibling elements of the BSON object. Sort keys involving nested arrays are not considered parallel, nor are sort keys which share the same array as a prefix.

Note

This behavior has always existed for sorting with find, but now in 3.6 find and aggregate share the same semantics.

Example

A collection contains the following document:

{a: [ {b: [1, 2]}, {b: [3, 4]} ]}

The following aggregation succeeds because the sort is performed on a nested array:

db.coll.aggregate([{$sort: {"a.b": 1}}])

Example

Similarly, if a collection contains the following document:

{a: [{b: 1, c: 1}, {b: 2, c: 2}]}

The following aggregation succeeds because the sort keys share the same array as a prefix:

db.coll.aggregate([{$sort: {"a.b": 1, "a.c": 1}}])

Example

However, in a collection that contains the following documents:

{ _id: 1, a: [ 1, 2 ], b: [ 1, 2 ]}
{ _id: 2, a: [ -3, 5 ], b: 0 }
{ _id: 3, a: [ -6, 12 ], b: 100 }

The following sort operation fails:

db.coll.aggregate([ { $sort: {a: 1, b: 1} } ])

MongoDB cannot sort on both the a and b fields because in the document with _id : 1 , the sibling fields a and b are both arrays. As a result, MongoDB encounters a parallel array during sort key generation and returns an error.

Update Operation Changes

New Fields in Updates

Starting in MongoDB 3.6, new fields added through update operations are appended in lexicographic order.

For example, a collection coll has the following document:

{ _id: 0, x: 0 }

The following update operation adds two new fields to the document:

db.coll.update({_id: 0}, {$set: {b: 0, a: 0}})

Starting in 3.6, MongoDB appends the new fields in lexicographic order. The updated document would be {_id : 0, x: 0, a: 0, b: 0}.

Earlier versions of MongoDB append the new fields in order of appearance in the update document. The updated document would be {_id : 0, x: 0, b: 0, a: 0}.

Fields Conflicting with arrayFilters Identifiers

Starting in MongoDB 3.6, fields that conflict with arrayFilters identifiers can no longer be updated.

For example, a collection coll has the following document:

{ _id: 0, x: { "$[]": 0 } }

The following update succeeds in earlier versions of MongoDB:

db.coll.update({_id: 0}, {$set: {"x.$[]": 1}})

In MongoDB 3.6 the update fails since the field name “$[]” conflicts with arrayFilters identifier syntax. For more information on arrayFilters see Specify arrayFilters for Array Update Operations.

Note

The new update behaviors apply only when featureCompatibilityVersion is set to 3.6.

Stricter Validation of $pop Arguments

Starting in 3.6 [1], $pop operator performs a stricter validation of its argument to require either:

  • -1 to remove the first element of an array, or
  • 1 to remove the last element in an array.

In earlier versions, $pop allowed:

  • any value less than 0 to remove the first element of an array, and
  • any value greater than or equal to 0 as well as non-numeric value to remove the last element in an array.
[1]Affects MongoDB deployments with featureCompatibilityVersion set to 3.6; e.g. new 3.6 deployments, upgraded deployments that have set featureCompatibilityVersion to 3.6.

Remove $pushAll Update Operator

MongoDB 3.6 removes the deprecated $pushAll operator. The operator has been deprecated since 2.4.

Instead of $pushAll, use the $push operator with the $each modifier. For example:

db.students.update(
   { name: "joe" },
   { $push: { scores: { $each: [ 90, 92, 85 ] } } }
)

Platform Support

  • MongoDB 3.6 discontinues support for versions of Windows prior to Windows Server 2008 R2 and Windows 7.
  • MongoDB 3.6 is not tested on APFS, the new filesystem in macOS 10.13 and may encounter errors.

General Compatibility Changes

MONGODB-CR Deprecation

As of MongoDB 3.6, MONGODB-CR authentication mechanism is deprecated. If you have not upgraded your MONGODB-CR authentication schema to SCRAM, see Upgrade to SCRAM.

Arbiter and Priority

Starting in MongoDB 3.6, arbiters have priority 0. When you upgrade a replica set to MongoDB 3.6, if the existing configuration has an arbiter with priority 1, MongoDB 3.6 reconfigures the arbiter to have priority 0.

Deprecate Master-Slave Replication

MongoDB 3.6 deprecates master-slave replication.

--nojournal Option with WiredTiger

In version 3.6, the --nojournal option is deprecated for replica set members using the WiredTiger storage engine.

Replica set members which use the WiredTiger storage engine should not use the --nojournal option. For more information about journaling, see Manage Journaling.

aggregate Command and Results

MongoDB 3.6 removes the option for the aggregate command to return its results as a single document.

If you run the aggregate command, you must include either the cursor option or the explain option.

Rather than run the aggregate command directly, most users should use the db.collection.aggregate() helper provided in the mongo shell or the equivalent helper in their driver. These helpers return a cursor unless using the explain option.

Aggregation Date to String Coercion

Starting in 3.6, a date coerced to a string in an aggregation expression will include milliseconds and is appended with the letter ‘Z’.

Example

// Documents.
{_id: 0, d: ISODate("2017-10-18T20:04:27.978Z")}
{_id: 1, d: ISODate("2017-10-18T20:04:28.192Z")}

// Query.
db.coll.aggregate({$project: {d: {$toLower: "$d"}}})

Prior to 3.6, this would return the dates as d: "2017-10-18t20:04:27" and d: "2017-10-18t20:04:28" respectively. In 3.6, the results include the milliseconds and letter ‘Z’: d: "2017-10-18t20:04:27.978z" and d: "2017-10-18t20:04:28.192z".

The change applies to the following aggregation operators:

Remove Diagnostic Logging Command and Option

MongoDB 3.6 removes the deprecated diagLogging command and mongod --diaglog option. Instead, use mongoreplay to capture, replay, and profile commands sent to your MongoDB deployment.

validate Operation

Starting in MongoDB 3.6, for the WiredTiger storage engine, only the full validation process will force a checkpoint and flush all in-memory data to disk before verifying the on-disk data.

In previous versions, the data validation process for the WT storage engine always forces a checkpoint.

For more information on the validate operation, see the validate command and the db.collection.validate() method.

Indexes Named *

Starting in 3.6, you cannot specify * as the index name during index creation nor can you delete indexes named * by specifying the index keys.

To delete existing indexes named *, delete the index before upgrading. To rename them, delete and recreate the index.

Deprecated Options

Changed in version 3.6.1.

  • MongoDB 3.6.1 deprecates the snapshot query option.

    For MMAPv1, use hint() on the { _id: 1} index instead to prevent a cursor from returning a document more than once if an intervening write operation results in a move of the document.

    For other storage engines, use hint() with { $natural : 1 } instead.

  • MongoDB 3.6.1 deprecates the $isolated option. For more information on read isolation, see Read Isolation, Consistency, and Recency. [2]

[2]Starting in version 4.0, MongoDB offers transactions.

Backwards Incompatible Features

The following 3.6 features require that featureCompatibilityVersion be set to "3.6":

3.6 deployments have the following default featureCompatibilityVersion values:

Deployments featureCompatibilityVersion
For new 3.6 deployments "3.6"
For deployments upgraded from 3.4 "3.4" until you setFeatureCompatibilityVersion to "3.6".

To view the featureCompatibilityVersion, see View FeatureCompatibilityVersion.

If you need to downgrade from 3.6, you must remove data related to all persisted incompatible features from your database before downgrading the binaries. See the 3.6 downgrade procedures.