Functional Differences: Amazon DocumentDB and MongoDB - Amazon DocumentDB

Functional Differences: Amazon DocumentDB and MongoDB

The following are the functional differences between Amazon DocumentDB (with MongoDB compatibility) and MongoDB.

Admin Databases and Collections

Amazon DocumentDB does not support the admin or local database nor MongoDB system.* or startup_log collections respectively.

Array Indexing

Amazon DocumentDB indexes an array as a single entry. Arrays larger than 2048 bytes cannot currently be indexed.

explain()

Amazon DocumentDB emulates the MongoDB 3.6 API on a purpose-built database engine that utilizes a distributes, fault-tolerant, self-healing storage system. As a result, query plans and the output of explain() may differ between Amazon DocumentDB and MongoDB. Customers who want control over their query plan can use the $hint operator to enforce selection of a preferred index.

Field Name Restrictions

Amazon DocumentDB does not support dots “.” in a document field name, for example, db.foo.insert({‘x.1’:1}).

Implicit Transactions

In Amazon DocumentDB, all CRUD statements (findAndModify, update, insert, delete) guarantee atomicity and consistency, even for operations that modify multiple documents. This behavior is different than MongoDB 3.6, which only provides atomic guarantees for commands that modify a single document. The following are examples of operations in Amazon DocumentDB that modify multiple documents that satisfy both atomic and consistent behaviors.

db.miles.update( { "credit_card": { $eq: true } }, { $mul: { "flight_miles.$[]": NumberInt(2) } }, { multi: true } )
db.miles.updateMany( { "credit_card": { $eq: true } }, { $mul: { "flight_miles.$[]": NumberInt(2) } } )
db.runCommand({ update: "miles", updates: [ { q: { "credit_card": { $eq: true } }, u: { $mul: { "flight_miles.$[]": NumberInt(2) } }, multi: true } ] })
db.products.deleteMany({ "cost": { $gt: 30.00 } })
db.runCommand({ delete: "products", deletes: [{ q: { "cost": { $gt: 30.00 } }, limit: 0 }] })

The individual operations that compose bulk operations such as updateMany and deleteMany are atomic but the entirety of the bulk operation is not atomic. For example, the entirety of the insertMany operation is atomic if the individual insert operations execute successfully without error. If an error is encountered with an insertMany operation, each individual insert statement within the insertMany operation will execute as an atomic operation.

Amazon DocumentDB currently supports implicit transactional semantics for single statement operations, as shown previously. Amazon DocumentDB currently does not support multi-statement transactions.

Index Builds

Amazon DocumentDB allows only one index build to occur on a collection at any given time (foreground or background). If operations such as createIndex() or dropIndex() occur on the same collection when an index build is currently in progress, the newly attempted operation will fail.

A Time to Live (TTL) index starts expiring documents after the index build (foreground or background) is completed.

MongoDB APIs, Operations, and Data Types

Amazon DocumentDB is compatible with the MongoDB 3.6 API. For an up-to-date list of supported functionality, see Supported MongoDB APIs, Operations, and Data Types.

The mongodump and mongorestore Utilities

Amazon DocumentDB does not support an admin database and thus does not dump or restore the admin database when using the mongodump or mongorestore utilities. When you create a new database in Amazon DocumentDB using mongorestore, you need to re-create the user roles in addition to the restore operation.

Multi-key Index

Amazon DocumentDB does not yet support creating a compound index with multiple keys on the same array. A workaround is to create individual indexes on the desired array fields because the Amazon DocumentDB query planner can use multiple indexes in a single query.

Result Ordering

Amazon DocumentDB does not guarantee implicit result sort ordering of result sets. To ensure the ordering of a result set, explicitly specify a sort order using sort().

The following example sorts the items in the inventory collection in descending order based on the stock field.

db.inventory.find().sort({ stock: -1 })

Retryable Writes

Starting with MongoDB 4.2 compatible drivers, retryable writes is enabled by default. However, Amazon DocumentDB does not currently support retryable writes. The functional difference will manifest itself in an error message similar to the following.

{"ok":0,"errmsg":"Unrecognized field: 'txnNumber'","code":9,"name":"MongoError"}

Retryable writes can be disabled via the connection string (for example, MongoClient("mongodb://my.mongodb.cluster/db?retryWrites=false")) or the MongoClient constructor’s keyword argument (for example, MongoClient("mongodb://my.mongodb.cluster/db", retryWrites=False)).

The following is a Python example that disables retryable writes in the connection string.

client = pymongo.MongoClient('mongodb://<username>:<password>@docdb-2019-03-17-16-49-12.cluster-ccuszbx3pn5e.us-east-1.docdb.amazonaws.com:27017/?replicaSet=rs0',w='majority',j=True,retryWrites=False)

Role-Based Access Control

As of March 26, 2020, Amazon DocumentDB supports role-based access control (RBAC) for built-in roles. To learn more see, Role-Based Access Control. Amazon DocumentDB does not yet support custom roles for RBAC.

Sparse Index

To use a sparse index that you have created in a query, you must use the $exists clause on the fields that cover the index. If you omit $exists, Amazon DocumentDB does not use the sparse index.

The following is an example.

db.inventory.count({ "stock": { $exists: true }})

Storage Compression

Amazon DocumentDB doesn't currently support compression for stored data or indexes. Data sizes for stored data and indexes might be larger than when you use other options.

Strings

Amazon DocumentDB does not allow null characters ( '\0' ) in strings.

db.inventory.insert({"description": "\0"}) WriteResult({ "writeError": { "code": 303, "errmsg": "Unsupported BSON : has null character in string" } })

Using $elemMatch Within an $all Expression

Amazon DocumentDB does not currently support the use of the $elemMatch operator within an $all expression. As a workaround, you can use the $and operator with $elemMatch as follows.

Original operation:

db.col.find({ qty: { $all: [ { "$elemMatch": { part: "xyz", qty: { $lt: 11 } } }, { "$elemMatch": { num: 40, size: "XL" } } ] } })

Updated operation:

db.col.find({ $and: [ { qty: { "$elemMatch": { part: "xyz", qty: { $lt: 11 } } } }, { qty: { "$elemMatch": { qty: 40, size: "XL" } } } ] })

$distinct, $regex, $elemMatch, and $lookup Indexing

Amazon DocumentDB does not currently support the ability to use indexes with the $distinct, $regex, $elemMatch, and $lookup operators. As a result, utilizing these operators will result in collection scans. Performing a filter or match before utilizing one of these operators will reduce the amount of data that needs to be scanned, and thus can improve performance.

$lookup

Amazon DocumentDB supports the ability to do equality matches (for example, left outer join) but does not support uncorrelated subqueries.