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.
Temas
Beneficios funcionales de Amazon DocumentDB
Transacciones implícitas
En Amazon DocumentDB, todas las declaraciones de CRUD (findAndModify
, update
, insert
y delete
) garantizan la atomicidad y la coherencia, incluso en operaciones que modifican varios documentos. Con el lanzamiento de Amazon DocumentDB 4.0, ahora se admiten transacciones explícitas que proporcionan propiedades ACID para operaciones de varios estados de cuenta y cobros. 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 propiedades ACID para operaciones de insertMany
, updateMany
y deleteMany
, 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.
Temas
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 varias 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 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 roles (RBAC) para roles integrados. Para obtener más información, consulte Control de acceso basado en roles.
Indexación de $regex
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
Temas
- operador $vectorSearch
- OpCountersCommand
- Bases de datos de administración y colecciones
- cursormaxTimeMS
- explain()
- Restricciones de nombres de campos
- Compilaciones de índices
- Búsqueda con una clave vacía en la ruta
- API, operaciones y tipos de datos de MongoDB
- Utilidades de mongodump y mongorestore
- Ordenación de los resultados
- Reintento de las escrituras
- Índices dispersos
- Uso de $elemMatch dentro de una expresión $all
- Indexación de $ne, $nin, $nor, $not, $exists y $elemMatch
- $lookup
operador $vectorSearch
Amazon DocumentDB no admite $vectorSearch
como operador independiente. En su lugar, admitimos vectorSearch
dentro del operador $search
. 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 queOpCountersCommand
de Amazon DocumentDB también excluye el comandofind
.Amazon DocumentDB tiene en cuenta los comandos internos para
OpCountersCommand
.
Bases de datos de administración 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 la API MongoDB 4.0 en un motor de base de datos personalizada que utiliza un sistema de almacenamiento distribuido, tolerante a fallos y de recuperación automática. 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 campos
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 ignoran la opción de creación de índices en segundo plano si se especifica en createIndexes o sus asistentes de intérprete de comandos createIndex()
y createIndexes()
.
Un índice de tiempo de vida (TTL) empieza a marcar los documentos como caducados en cuanto se completa la operación de 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.
API, operaciones y tipos de datos de MongoDB
Amazon DocumentDB es compatible con las API de MongoDB 3.6 y 4.0. Para ver la lista actualizada de funcionalidades admitidas, consulte APIsMongoDB, operaciones y tipos de datos compatibles en Amazon DocumentDB.
Utilidades de mongodump
y mongorestore
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 los 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"}
El reintento de las escrituras se puede deshabilitar a través de la cadena de conexión (por ejemplo, MongoClient("mongodb://my.mongodb.cluster/db?retryWrites=false"))
) o el argumento de la palabra clave del constructor MongoClient (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.
Uso de $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" } } } ] })
Indexación de $ne
, $nin
, $nor
, $not
, $exists
y $elemMatch
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 posibilidad de llevar a cabo coincidencias de igualdad (por ejemplo, combinació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
.
nota
Actualmente, la opción allowDiskUse
no es compatible con el comando find
. La opción solo se admite como parte de la agregación. Recomendamos utilizar el marco de agregación con allowDiskUse:true
para gestionar consultas grandes que puedan superar los límites de memoria.
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 Creación de perfiles de operaciones en 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\\" }}"