Diferencias funcionales: Amazon DocumentDB y MongoDB - Amazon DocumentDB

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

Diferencias funcionales: Amazon DocumentDB y MongoDB

A continuación se explican las diferencias funcionales entre Amazon DocumentDB (con compatibilidad con MongoDB) y MongoDB.

Ventajas funcionales de Amazon DocumentDB

Transacciones implícitas

En Amazon DocumentDB, todas las CRUD instrucciones (,findAndModify, updateinsert,delete) garantizan la atomicidad y la coherencia, incluso para las operaciones que modifican varios documentos. Con el lanzamiento de Amazon DocumentDB 4.0, ahora se admiten transacciones explícitas que proporcionan ACID propiedades para operaciones con varios estados y recopilaciones múltiples. Para obtener más información sobre el uso de transacciones en Amazon DocumentDB, consulte Transacciones en Amazon DocumentDB.

A continuación se muestran ejemplos de operaciones en Amazon DocumentDB que modifican varios documentos que cumplen los comportamientos de atomicidad y coherencia.

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 }] })

Las operaciones individuales que componen operaciones en bloque tales como updateMany y deleteMany son atómicas, pero la operación en bloque en su conjunto no es atómica. Por ejemplo, la operación insertMany en su conjunto es atómica si las operaciones de inserción individuales se ejecutan correctamente sin errores. Si se detecta algún error en una operación insertMany, cada instrucción de inserción individual dentro de la operación insertMany se ejecutará como una operación atómica. Si necesita ACID propiedades para y deleteMany operaciones insertManyupdateMany, se recomienda utilizar una transacción.

Diferencias funcionales actualizadas

Amazon DocumentDB continúa mejorando la compatibilidad con MongoDB al trabajar a partir de las capacidades que nuestros clientes nos piden que creemos. Esta sección contiene las diferencias funcionales que hemos eliminado en Amazon DocumentDB para facilitar las migraciones y la creación de aplicaciones para nuestros clientes.

Indexación de matrices

A partir del 23 de abril de 2020, Amazon DocumentDB admite la capacidad de indexar matrices mayores de 2048 bytes. El límite para un elemento individual en una matriz se mantiene en 2048 bytes, lo que es coherente con MongoDB.

Si crea un nuevo índice, no se necesita ninguna acción para aprovechar la funcionalidad mejorada. Si tiene un índice existente, puede aprovechar la funcionalidad mejorada borrando el índice y después volviéndolo a crear. La versión del índice actual con las capacidades mejoradas es "v" : 3.

nota

En el caso de los clústeres de producción, el borrado del índice puede tener un impacto en el rendimiento de la aplicación. Le recomendamos que primero pruebe y proceda con precaución al realizar cambios en un sistema de producción. Además, el tiempo que tardará en volver a crear el índice será una función del tamaño total de los datos de la colección.

Puede consultar la versión de los índices mediante el siguiente comando.

db.collection.getIndexes()

La salida de esta operación será similar a lo que se indica a continuación. En esta salida, la versión del índice es "v" : 3, que es la versión de índice más actual.

[ { "v" : 3, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.test" } ]

Índices de múltiples claves

A partir del 23 de abril de 2020, Amazon DocumentDB admite la capacidad de crear un índice compuesto por varias claves en la misma matriz.

Si crea un nuevo índice, no se necesita ninguna acción para aprovechar la funcionalidad mejorada. Si tiene un índice existente, puede aprovechar la funcionalidad mejorada borrando el índice y después volviéndolo a crear. La versión del índice actual con las capacidades mejoradas es "v" : 3.

nota

En el caso de los clústeres de producción, el borrado del índice puede tener un impacto en el rendimiento de la aplicación. Le recomendamos que primero pruebe y proceda con precaución al realizar cambios en un sistema de producción. Además, el tiempo que tardará en volver a crear el índice será una función del tamaño total de los datos de la colección.

Puede consultar la versión de los índices mediante el siguiente comando.

db.collection.getIndexes()

La salida de esta operación será similar a lo que se indica a continuación. En esta salida, la versión del índice es "v" : 3, que es la versión de índice más actual.

[ { "v" : 3, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.test" } ]

Caracteres nulos en las cadenas

A partir del 22 de junio de 2020, Amazon DocumentDB admite ahora caracteres nulos ('\0') en cadenas.

Control de acceso con base en roles

A partir del 26 de marzo de 2020, Amazon DocumentDB admite el control de acceso basado en funciones (RBAC) para las funciones integradas. Para obtener más información, consulte Control de acceso basado en roles.

$regexindexación

A partir del 22 de junio de 2020, Amazon DocumentDB admite la capacidad de los operadores $regex de utilizar un índice.

Para utilizar un índice con el operador $regex, debe utilizar el comando hint(). Al utilizar hint(), debe especificar el nombre del campo en el que está aplicando $regex. Por ejemplo, si tiene un índice en el campo product con el nombre de índice p_1, db.foo.find({product: /^x.*/}).hint({product:1}) utilizará el índice p_1, pero db.foo.find({product: /^x.*/}).hint(“p_1”) no utilizará el índice. Puede comprobar si se elige un índice mediante el comando explain() o haciendo uso del generador de perfiles para registrar consultas lentas. Por ejemplo, db.foo.find({product: /^x.*/}).hint(“p_1”).explain().

nota

Solo puede usarse un índice cada vez con el método hint().

El uso de un índice en una consulta $regex está optimizado para consultas regex que usan un prefijo y no especifican las opciones I, m o o de regex.

Al utilizar un índice con $regex, se recomienda crear un índice en campos altamente selectivos donde el número de valores duplicados sea inferior al 1 % del número total de documentos de la colección. Por ejemplo, si la colección cuenta con 100 000 documentos, solo cree índices en campos donde el mismo valor se produzca 1000 veces o menos.

Proyección para documentos anidados

Existe una diferencia funcional con el operador $project entre Amazon DocumentDB y MongoDB en la versión 3.6 que se ha resuelto en Amazon DocumentDB 4.0, pero seguirá sin ser compatible con Amazon DocumentDB 3.6.

Amazon DocumentDB 3.6 solo tiene en cuenta el primer campo de un documento anidado al aplicar una proyección, mientras que MongoDB 3.6 analizará los subdocumentos y aplicará la proyección también a cada subdocumento.

Por ejemplo: si la proyección es “a.b.c”: 1, se comportará como se esperaba tanto en Amazon DocumentDB como en MongoDB. Sin embargo, si la proyección es {a:{b:{c:1}}}, Amazon DocumentDB 3.6 solo aplicará la proyección a a y no a b o c. En Amazon DocumentDB 4.0, la proyección {a:{b:{c:1}}} se aplicará a a, b y c.

Diferencias funcionales con MongoDB

Amazon DocumentDB no es compatible $vectorSearch como operador independiente. En su lugar, lo apoyamos, vectorSearch dentro del $search operador. Para obtener más información, consulte Búsqueda vectorial para Amazon DocumentDB.

OpCountersCommand

El comportamiento de OpCountersCommand de Amazon DocumentDB se desvía de opcounters.command de MongoDB de la siguiente manera:

  • opcounters.command de MongoDB cuenta todos los comandos excepto el de insertar, actualizar y eliminar, mientras que OpCountersCommand de Amazon DocumentDB también excluye el comando find.

  • Amazon DocumentDB incluye algunos comandos internos en el. OpCountersCommand

Administre bases de datos y colecciones

Amazon DocumentDB no admite la base de datos de administración o local ni las colecciones system.* o startup_log de MongoDB, respectivamente.

cursormaxTimeMS

En Amazon DocumentDB, cursor.maxTimeMS restablece el contador de cada solicitud de getMore. Por lo tanto, si se especifica un maxTimeMS de 3000 MS, la consulta tarda 2800 MS y cada solicitud de getMore posterior tarda 300 MS, por lo que el cursor no agotará el tiempo de espera. El tiempo de espera del cursor solo se agotará cuando una sola operación, ya sea la consulta o una solicitud de getMore individual, dure más que el maxTimeMS especificado. Además, el barrido que comprueba el tiempo de ejecución del cursor funciona con una granularidad de cinco (5) minutos.

explain()

Amazon DocumentDB emula MongoDB 4.0 API en un motor de base de datos diseñado específicamente que utiliza un sistema de almacenamiento distribuido, tolerante a errores y autorreparable. Como resultado, los planes de consulta y la salida de explain() pueden diferir entre Amazon DocumentDB y MongoDB. Los clientes que deseen controlar su plan de consulta pueden utilizar el operador $hint para aplicar la selección de un índice preferido.

Restricciones de nombres de campo

Amazon DocumentDB no admite puntos “.” en el nombre de un campo de un documento como, por ejemplo, db.foo.insert({‘x.1’:1}).

Amazon DocumentDB tampoco admite el prefijo $ en los nombres de campo.

Por ejemplo, pruebe el siguiente comando en Amazon DocumentDB o MongoDB:

rs0:PRIMARY< db.foo.insert({"a":{"$a":1}})

MongoDB devolverá lo siguiente:

WriteResult({ "nInserted" : 1 })

Amazon DocumentDB devolverá un error:

WriteResult({ "nInserted" : 0, "writeError" : { "code" : 2, "errmsg" : "Document can't have $ prefix field names: $a" } })
nota

Esta diferencia funcional tiene una excepción. Se han habilitado los siguientes nombres de campo que comienzan con el prefijo $ y se pueden utilizar correctamente en Amazon DocumentDB: $id, $ref y $db.

Compilaciones de índices

Amazon DocumentDB solo permite una operación de creación de índice en una colección al mismo tiempo. Ya sea en primer plano o en segundo plano. Si operaciones, tales como createIndex() o dropIndex(), se producen en la misma colección cuando una operación de creación de índice está actualmente en curso, se producirá un error en la operación que se ha intentado realizar recientemente.

De forma predeterminada, las compilaciones de índices en Amazon DocumentDB y MongoDB versión 4.0 se producen en segundo plano. La versión 4.2 y posteriores de MongoDB ignora la opción de creación del índice en segundo plano si se especifica o sus ayudantes de createIndexes shell y. createIndex() createIndexes()

Un índice Time to Live (TTL) comienza a caducar los documentos una vez finalizada la creación del índice.

Búsqueda con una clave vacía en la ruta

Si busca con una clave que incluye una cadena vacía como parte de la ruta (por ejemplo, x., x..b) y el objeto tiene una ruta de clave de cadena vacía (por ejemplo, {"x" : [ { "" : 10 }, { "b" : 20 } ]}) dentro de una matriz, Amazon DocumentDB devolverá resultados diferentes a los que arrojaría si usted ejecutara la misma búsqueda en MongoDB.

En MongoDB, la búsqueda de rutas con clave vacía dentro de una matriz funciona tal y como se esperaba cuando la clave de cadena vacía no está al final de la búsqueda de rutas. Sin embargo, cuando la clave de cadena vacía está al final de la búsqueda de rutas, no busca en la matriz.

Sin embargo, en Amazon DocumentDB, solo se lee el primer elemento de la matriz, ya que getArrayIndexFromKeyString convierte una cadena vacía en 0, por lo que se trata a la búsqueda de claves de cadena como a una búsqueda de índice de matriz.

APIsMongoDB, operaciones y tipos de datos

Amazon DocumentDB es compatible con MongoDB 3.6 y 4.0. APIs Para obtener una up-to-date lista de las funciones compatibles, consulte. APIsMongoDB, operaciones y tipos de datos compatibles en Amazon DocumentDB

mongodumpy mongorestore utilidades

Amazon DocumentDB no admite una base de datos de administración y, por lo tanto, no vuelca ni restaura la base de datos de administración cuando se usan las utilidades mongodump o mongorestore. Al crear una nueva base de datos en Amazon DocumentDB mediante mongorestore, debe volver a crear los roles de usuario además de la operación de restauración.

nota

Recomendamos las herramientas de base de datos de MongoDB hasta la versión 100.6.1 inclusive para Amazon DocumentDB. Puede acceder a las descargas de las herramientas de base de datos de MongoDB aquí.

Ordenación de resultados

Amazon DocumentDB no garantiza la ordenación implícita de los conjuntos de resultados. Para garantizar la ordenación de un conjunto de resultados, especifique explícitamente un criterio de ordenación utilizando sort().

En el siguiente ejemplo, se ordenan los elementos de la colección de inventario en orden descendente en función del campo "stock".

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

Cuando se utiliza la etapa de agregación de $sort, el orden de clasificación no se conserva a menos que la etapa $sort sea la última etapa del proceso de agregación. Cuando se utiliza la etapa de agregación de $sort en combinación con la etapa de agregación de $group, la etapa de agregación de $sort solo se aplica a los acumuladores de $first y $last. En Amazon DocumentDB 4.0, se agregó compatibilidad con $push para respetar el orden de clasificación de la etapa de $sort anterior.

Reintento de las escrituras

A partir de los controladores compatibles con MongoDB 4.2, el reintento de las escrituras está habilitado de forma predeterminada. Sin embargo, actualmente Amazon DocumentDB no admite el reintento de las escrituras. La diferencia funcional se manifestará en un mensaje de error similar al siguiente.

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

Las escrituras reintentables se pueden deshabilitar mediante la cadena de conexión (por ejemplo,) MongoClient("mongodb://my.mongodb.cluster/db?retryWrites=false")) o el argumento de palabra clave del MongoClient constructor (por ejemplo,. MongoClient("mongodb://my.mongodb.cluster/db", retryWrites=False))

A continuación, se muestra un ejemplo de Python en el que se deshabilita el reintento de las escrituras en la cadena de conexión.

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)

Índices dispersos

Para utilizar un índice disperso que haya creado en una consulta, debe utilizar la cláusula $exists en los campos incluidos en el índice. Si omite $exists, Amazon DocumentDB no utiliza el índice disperso.

A continuación, se muestra un ejemplo.

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

Para índices dispersos de varias claves, Amazon DocumentDB no admite una restricción de clave única si la búsqueda de un documento da como resultado un conjunto de valores y solo falta un subconjunto de los campos indexados. Por ejemplo, createIndex({"a.b" : 1 }, { unique : true, sparse :true }) no se admite con la entrada "a" : [ { "b" : 2 }, { "c" : 1 } ], ya que "a.c" se almacena en el índice.

Usar $elemMatch dentro de una expresión $all

Actualmente, Amazon DocumentDB no admite el uso del operador $elemMatch dentro de una expresión $all. Como solución alternativa, puede usar el operador $and con $elemMatch de la siguiente manera.

Operación original:

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

Operación actualizada:

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

$ne,$nin, $nor$not$exists, e $elemMatch indexación

Actualmente Amazon DocumentDB no admite la capacidad de usar índices con los operadores $ne, $nin, $nor, $not, $exists y $distinct. Como resultado, el uso de estos operadores hará escaneos de recopilación. Realizar un filtro o una coincidencia antes de usar uno de estos operadores reducirá la cantidad de datos que se deben analizar y, por lo tanto, puede mejorar el rendimiento.

Amazon DocumentDB agregó compatibilidad con escaneos de índices con el operador de $elemMatch en Amazon DocumentDB 5.0 y clústeres elásticos. Los escaneos de índices son compatibles cuando el filtro para solo consultas tiene un nivel de filtro de $elemMatch, pero no son compatibles si se incluye una consulta de $elemMatch anidada.

La forma de consulta de $elemMatch que admite escaneos de índices en Amazon DocumentDB 5.0:

db.foo.find( { "a": {$elemMatch: { "b": "xyz", "c": "abc"} } })

La forma de consulta de $elemMatch que no admite escaneos de índices en Amazon DocumentDB 5.0:

db.foo.find( { "a": {$elemMatch: { "b": {$elemMatch: { "d": "xyz", "e": "abc"} }} } })

$lookup

Amazon DocumentDB admite la capacidad de realizar coincidencias de igualdad (por ejemplo, unión externa izquierda) y también admite subconsultas no correlacionadas, pero no admite subconsultas correlacionadas.

Uso de un índice con $lookup

Ahora puede utilizar un índice con el operador de la etapa de $lookup. Según su caso de uso, existen varios algoritmos de indexación que puede utilizar para optimizar el rendimiento. En esta sección se explican los diferentes algoritmos de indexación para $lookup y se le ayuda a elegir el mejor para su carga de trabajo.

De forma predeterminada, Amazon DocumentDB utilizará el algoritmo hash cuando se utilice allowDiskUse:false y se realizará la fusión de clasificación cuando se use allowDiskUse:true. En algunos casos de uso, puede ser preferible obligar al optimizador de consultas a utilizar un algoritmo diferente. A continuación se muestran los diferentes algoritmos de indexación que puede utilizar el operador de agregación de $lookup:

  • Bucle anidado: un plan de bucles anidados suele ser beneficioso para una carga de trabajo si la colección externa es inferior a 1 GB y el campo de la colección externa tiene un índice. Si se utiliza el algoritmo de bucle anidado, el plan explicativo mostrará la etapa como NESTED_LOOP_LOOKUP.

  • Fusión y ordenación: un plan de fusión y ordenación suele ser beneficioso para una carga de trabajo si la colección externa no tiene un índice en el campo utilizado en la búsqueda y el conjunto de datos de trabajo no cabe en la memoria. Si se utiliza el algoritmo de fusión y ordenación, el plan explicativo mostrará la etapa como SORT_LOOKUP.

  • Hash: un plan de hash suele ser beneficioso para una carga de trabajo si la colección externa ocupa menos de 1 GB y el conjunto de datos de trabajo cabe en la memoria. Si se utiliza el algoritmo de hash, el plan explicativo mostrará la etapa como HASH_LOOKUP.

Puede identificar el algoritmo de indexación que se utiliza para el operador de $lookup, utilice explain en la consulta. A continuación se muestra un ejemplo.

db.localCollection.explain(). aggregate( [ { $lookup: { from: "foreignCollection", localField: "a", foreignField: "b", as: "joined" } } ] output { "queryPlanner" : { "plannerVersion" : 1, "namespace" : "test.localCollection", "winningPlan" : { "stage" : "SUBSCAN", "inputStage" : { "stage" : "SORT_AGGREGATE", "inputStage" : { "stage" : "SORT", "inputStage" : { "stage" : "NESTED_LOOP_LOOKUP", "inputStages" : [ { "stage" : "COLLSCAN" }, { "stage" : "FETCH", "inputStage" : { "stage" : "COLLSCAN" } } ] } } } } }, "serverInfo" : { "host" : "devbox-test", "port" : 27317, "version" : "3.6.0" }, "ok" : 1 }

Como alternativa al uso del método de explain(), puede usar el generador de perfiles para revisar el algoritmo que se utiliza al usar el operador de $lookup. Para obtener más información acerca del generador de perfiles, consulte Elaboración de perfiles de las operaciones de Amazon DocumentDB.

Uso de una planHint

Si desea obligar al optimizador de consultas a utilizar un algoritmo de indexación diferente con $lookup, puede utilizar un planHint. Para ello, utilice el comentario en las opciones de la etapa de agregación para forzar un plan diferente. A continuación, se muestra un ejemplo de la sintaxis del comentario:

comment : { comment : “<string>”, lookupStage : { planHint : “SORT” | “HASH” | "NESTED_LOOP" } }

A continuación, se muestra un ejemplo del uso de planHint para obligar al optimizador de consultas a utilizar el algoritmo de indexación HASH:

db.foo.aggregate( [ { $lookup: { from: "foo", localField: "_id", foreignField: "_id", as: "joined" }, } ], { comment : "{ \\"lookupStage\\" : { \\"planHint\\": \\"HASH\\" }}"

Para probar qué algoritmo se adapta mejor a su carga de trabajo, puede utilizar el parámetro executionStats del método explain para medir el tiempo de ejecución de la etapa de $lookup y, al mismo tiempo, modificar el algoritmo de indexación (es decir, HASH/SORT/NESTED_LOOP).

El siguiente ejemplo muestra cómo utilizar executionStats para medir el tiempo de ejecución de la etapa de $lookup mediante el algoritmo de SORT.

db.foo.explain(“executionStats”).aggregate( [ { $lookup: { from: "foo", localField: "_id", foreignField: "_id", as: "joined" }, } ], { comment : "{ \\"lookupStage\\" : { \\"planHint\": \\"SORT\\" }}"