Différences fonctionnelles : Amazon DocumentDB et MongoDB - Amazon DocumentDB

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Différences fonctionnelles : Amazon DocumentDB et MongoDB

Voici les différences fonctionnelles entre Amazon DocumentDB (compatible avec MongoDB) et MongoDB.

Avantages fonctionnels d'Amazon DocumentDB

Transactions implicites

Dans Amazon DocumentDB, toutes les instructions CRUD (findAndModify,, updateinsert,delete) garantissent l'atomicité et la cohérence, même pour les opérations qui modifient plusieurs documents. Avec le lancement d'Amazon DocumentDB 4.0, les transactions explicites fournissant des propriétés ACID pour les opérations multi-instructions et multi-collections sont désormais prises en charge. Pour en savoir plus sur l'utilisation des transactions dans Amazon DocumentDB, consultez. Transactions dans Amazon DocumentDB

Vous trouverez ci-dessous des exemples d'opérations dans Amazon DocumentDB qui modifient plusieurs documents répondant à la fois à des comportements atomiques et cohérents.

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

Les opérations individuelles qui composent les opérations en bloc comme updateMany et deleteMany sont atomiques. Toutefois, cela ne signifie pas que les opérations en vrac sont entièrement atomiques. Par exemple, l'intégralité de l'opération insertMany est atomique si les opérations d'insertion individuelles s'exécutent avec succès sans erreur. En cas d'erreur lors d'une insertMany opération, chaque instruction d'insertion individuelle contenue dans l'insertManyopération sera exécutée comme une opération atomique. Si vous avez besoin de propriétés ACID pour les insertMany deleteMany opérations et les opérations, il est recommandé d'utiliser une transaction. updateMany

Différences fonctionnelles mises à jour

Amazon DocumentDB continue d'améliorer la compatibilité avec MongoDB en remontant les fonctionnalités que nos clients nous demandent de développer. Cette section contient les différences fonctionnelles que nous avons supprimées dans Amazon DocumentDB afin de faciliter les migrations et la création d'applications pour nos clients.

Indexation de tableaux

Depuis le 23 avril 2020, Amazon DocumentDB permet désormais d'indexer des tableaux de plus de 2 048 octets. La limite pour un élément individuel dans un tableau reste de 2 048 octets, ce qui est cohérent avec MongoDB.

Si vous créez un nouvel index, aucune action n'est nécessaire pour profiter de la fonctionnalité améliorée. Si vous avez un index existant, vous pouvez profiter de la fonctionnalité améliorée en l'abandonnant, puis en le recréant. La version d'index actuelle avec les capacités améliorées est "v" : 3.

Note

Pour les clusters de production, la suppression de l'index peut avoir un impact sur les performances de votre application. Nous vous recommandons d'abord de tester et de procéder avec prudence lorsque vous apportez des modifications à un système de production. De plus, le temps qu'il faudra pour recréer l'index dépendra de la taille globale des données de la collection.

Vous pouvez interroger la version de vos index à l'aide de la commande suivante.

db.collection.getIndexes()

Le résultat de cette opération ressemble à ceci. Dans cette sortie, la version de l'index est "v" : 3, qui est la version d'index la plus récente.

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

Index à clés multiples

Depuis le 23 avril 2020, Amazon DocumentDB permet désormais de créer un index composé avec plusieurs clés dans le même tableau.

Si vous créez un nouvel index, aucune action n'est nécessaire pour profiter de la fonctionnalité améliorée. Si vous avez un index existant, vous pouvez profiter de la fonctionnalité améliorée en l'abandonnant, puis en le recréant. La version d'index actuelle avec les capacités améliorées est "v" : 3.

Note

Pour les clusters de production, la suppression de l'index peut avoir un impact sur les performances de votre application. Nous vous recommandons d'abord de tester et de procéder avec prudence lorsque vous apportez des modifications à un système de production. De plus, le temps qu'il faudra pour recréer l'index dépendra de la taille globale des données de la collection.

Vous pouvez interroger la version de vos index à l'aide de la commande suivante.

db.collection.getIndexes()

Le résultat de cette opération ressemble à ceci. Dans cette sortie, la version de l'index est "v" : 3, qui est la version d'index la plus récente.

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

Caractères nuls dans les chaînes

Depuis le 22 juin 2020, Amazon DocumentDB prend désormais en charge les caractères nuls ('\0') dans les chaînes.

Contrôle d’accès basé sur les rôles

Depuis le 26 mars 2020, Amazon DocumentDB prend en charge le contrôle d'accès basé sur les rôles (RBAC) pour les rôles intégrés. Pour en savoir plus, consultez Contrôle d'accès basé sur les rôles.

$regexindexation

Depuis le 22 juin 2020, Amazon DocumentDB permet désormais aux $regex opérateurs d'utiliser un index.

Pour utiliser un index avec l'opérateur $regex, vous devez utiliser la commande hint(). Lorsque vous utilisez hint(), vous devez spécifier le nom du champ auquel vous appliquez le $regex. Par exemple, si vous avez un index sur le champ product avec le nom d'index p_1, db.foo.find({product: /^x.*/}).hint({product:1}) utilisera l'index p_1, mais db.foo.find({product: /^x.*/}).hint(“p_1”) n'utilisera pas l'index. Vous pouvez vérifier si un index est choisi à l'aide de la commande explain() ou du profileur pour consigner les requêtes lentes. Par exemple, db.foo.find({product: /^x.*/}).hint(“p_1”).explain().

Note

La méthode hint() ne peut être utilisée qu'avec un index à la fois.

L'utilisation d'un index pour une requête $regex est optimisée pour les requêtes regex qui utilisent un préfixe et ne spécifient pas les options regex i, m ou o.

Lorsque vous utilisez un index avec $regex, il est recommandé de créer un index sur des champs hautement sélectifs où le nombre de valeurs en double est inférieur à 1 % du nombre total de documents de la collection. Par exemple, si votre collection contient 100 000 documents, créez uniquement des index sur les champs où la même valeur se produit 1 000 fois ou moins.

Projection pour les documents imbriqués

Il existe une différence fonctionnelle d'$projectopérateur entre Amazon DocumentDB et MongoDB dans la version 3.6 qui a été résolue dans Amazon DocumentDB 4.0 mais ne sera toujours pas prise en charge dans Amazon DocumentDB 3.6.

Amazon DocumentDB 3.6 ne prend en compte que le premier champ d'un document imbriqué lors de l'application d'une projection, tandis que MongoDB 3.6 analyse les sous-documents et applique également la projection à chaque sous-document.

Par exemple : si la projection est le cas“a.b.c”: 1, le comportement fonctionne comme prévu dans Amazon DocumentDB et MongoDB. Toutefois, si la projection est le cas{a:{b:{c:1}}}, Amazon DocumentDB 3.6 appliquera uniquement la projection à a et non b à ou. c Dans Amazon DocumentDB 4.0, la projection {a:{b:{c:1}}} sera appliquée à ab, et. c

Différences fonctionnelles avec MongoDB

Amazon DocumentDB n'est pas pris en charge en $vectorSearch tant qu'opérateur indépendant. Au lieu de cela, nous soutenons, au vectorSearch sein de l'$searchopérateur. Pour de plus amples informations, veuillez consulter Recherche vectorielle pour Amazon DocumentDB.

OpCountersCommand

Le OpCountersCommand comportement d'Amazon DocumentDB diffère de celui de MongoDB comme suit : opcounters.command

  • MongoDB opcounters.command compte toutes les commandes sauf les commandes insert, update et delete, tandis que Amazon DocumentDB exclut OpCountersCommand également la find commande.

  • Amazon DocumentDB compte certaines commandes internes dans le. OpCountersCommand

Bases de données et collections d'administration

Amazon DocumentDB ne prend pas en charge l'administration ou la base de données locale, ni MongoDB system.* ou les collections respectivement. startup_log

cursormaxTimeMS

Dans Amazon DocumentDB, cursor.maxTimeMS réinitialise le compteur pour chaque demande. getMore Ainsi, si une valeur de 3 000 MS maxTimeMS est spécifiée, que la requête prend 2 800 ms et que chaque getMore demande suivante prend 300 MS, le curseur n'expirera pas. Le curseur n'expire que lorsqu'une seule opération, qu'il s'agisse de la requête ou d'une getMore demande individuelle, prend plus que ce qui est spécifiémaxTimeMS. De plus, le balayeur qui vérifie le temps d'exécution du curseur fonctionne à une granularité de cinq (5) minutes.

explain()

Amazon DocumentDB émule les versions 3.6, 4.0 et 5.0 de MongoDB APIs sur un moteur de base de données spécialement conçu qui utilise un système de stockage distribué, tolérant aux pannes et autoréparateur. Par conséquent, les plans de requête et le résultat de explain() peuvent différer entre Amazon DocumentDB et MongoDB. Les clients qui souhaitent contrôler leur plan de requête peuvent utiliser l'opérateur $hint pour appliquer la sélection d'un index préféré.

Constitutions d'index

Amazon DocumentDB autorise la création d'un seul index sur une collection à la fois. Au premier plan ou en arrière-plan. Si des opérations telles que createIndex() ou dropIndex() se produisent sur la même collection lorsqu'une génération d'index est en cours, l'opération nouvellement tentée échoue.

Par défaut, les compilations d'index dans Amazon DocumentDB et MongoDB version 4.0 s'effectuent en arrière-plan. MongoDB version 4.2 et versions ultérieures ignorent l'option de création d'index d'arrière-plan si elle est spécifiée à CreateIndexes ou à ses assistants shell et. createIndex() createIndexes()

Un index Time to Live (TTL) commence à expirer les documents une fois la création de l'index terminée.

Recherche avec une clé vide dans le chemin

Lorsque vous recherchez une clé qui inclut une chaîne vide dans le chemin (par exemplex.,x..b) et que l'objet possède un chemin de clé de chaîne vide (par exemple{"x" : [ { "" : 10 }, { "b" : 20 } ]}) dans un tableau, Amazon DocumentDB renvoie des résultats différents de ceux obtenus si vous exécutiez la même recherche dans MongoDB.

Dans MongoDB, la recherche du chemin de clé vide dans le tableau fonctionne comme prévu lorsque la clé de chaîne vide ne se trouve pas à la fin de la recherche de chemin. Cependant, lorsque la clé de chaîne vide se trouve à la fin de la recherche du chemin, elle n'apparaît pas dans le tableau.

Cependant, dans Amazon DocumentDB, seul le premier élément du tableau est lu, car il getArrayIndexFromKeyString convertit une chaîne vide en chaîne. La recherche par clé de chaîne est donc traitée comme une recherche d'index de tableau. 0

MongoDB APIs, opérations et types de données

Amazon DocumentDB est compatible avec les versions 3.6, 4.0 et 5.0 de MongoDB. APIs Pour obtenir la up-to-date liste des fonctionnalités prises en charge, consultezMongoDB APIs, opérations et types de données pris en charge dans Amazon DocumentDB.

mongodumpet mongorestore services publics

Amazon DocumentDB ne prend pas en charge une base de données d'administration et ne vide donc ni ne restaure la base de données d'administration lors de l'utilisation des utilitaires mongodump ormongorestore. Lorsque vous créez une nouvelle base de données dans Amazon DocumentDB à l'aide demongorestore, vous devez recréer les rôles utilisateur en plus de l'opération de restauration.

Note

Nous recommandons les outils de base de données MongoDB jusqu'à la version 100.6.1 incluse pour Amazon DocumentDB. Vous pouvez accéder aux téléchargements des outils de base de données MongoDB ici.

Ordre des résultats

Amazon DocumentDB ne garantit pas l'ordre de tri implicite des ensembles de résultats. Pour garantir l'ordre d'un jeu de résultats, spécifiez explicitement un ordre de tri en utilisant sort().

L'exemple suivant trie les éléments de la collecte d'inventaire par ordre décroissant en fonction du champ stock.

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

Lors de l'utilisation de l'étape d'$sortagrégation, l'ordre de tri n'est pas préservé, sauf si l'$sortétape est la dernière étape du pipeline d'agrégation. Lorsque l'étape d'$sortagrégation est utilisée en combinaison avec la phase d'$group$sortagrégation, l'étape d'agrégation est uniquement appliquée aux $last accumulateurs $first et. Dans Amazon DocumentDB 4.0, la prise en charge du respect de l'ordre de tri par rapport $push à l'étape précédente $sort a été ajoutée.

écritures réessayables

À partir des pilotes compatibles avec MongoDB 4.2, les écritures réessayables sont activées par défaut. Cependant, Amazon DocumentDB ne prend actuellement pas en charge les écritures réessayables. La différence fonctionnelle se manifeste dans un message d'erreur similaire à ce qui suit.

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

Les écritures réessayables peuvent être désactivées via la chaîne de connexion (par exemple,MongoClient("mongodb://my.mongodb.cluster/db?retryWrites=false")) ou l'argument mot-clé du MongoClient constructeur (par exemple,). MongoClient("mongodb://my.mongodb.cluster/db", retryWrites=False)

Voici un exemple Python qui désactive les écritures réessayables dans la chaîne de connexion.

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)

Index fragmenté

Pour utiliser un index fragmenté que vous avez créée dans une requête, vous devez utiliser la clause $exists sur les champs qui couvrent l'index. Si vous omettez$exists, Amazon DocumentDB n'utilisera pas l'index clairsemé.

Voici un exemple.

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

Pour les index multiclés épars, Amazon DocumentDB ne prend pas en charge une contrainte de clé unique si la recherche d'un document aboutit à un ensemble de valeurs et que seul un sous-ensemble des champs indexés est manquant. Par exemple, createIndex({"a.b" : 1 }, { unique : true, sparse :true }) n’est pas pris en charge, étant donné l'entrée de "a" : [ { "b" : 2 }, { "c" : 1 } ], car "a.c" est stocké dans l'index.

Utilisation $elemMatch dans une $all expression

Amazon DocumentDB ne prend actuellement pas en charge l'utilisation de l'$elemMatchopérateur dans une $all expression. Comme solution de contournement, vous pouvez utiliser l'opérateur $and avec $elemMatch comme suit.

Opération d'origine :

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

Opération mise à jour :

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

$ne,$nin, $nor$not,$exists, et $elemMatch indexation

Amazon DocumentDB ne prend actuellement pas en charge la possibilité d'utiliser des index avec les opérateurs$ne,$nin,$nor, $not$exists, et. $distinct Par conséquent, l'utilisation de ces opérateurs entraînera des scans des collections. L'exécution d'un filtre ou d'une correspondance avant d'utiliser l'un de ces opérateurs permet de réduire la quantité de données à scanner et d'améliorer ainsi les performances.

Amazon DocumentDB a ajouté la prise en charge des scans d'index avec l'$elemMatchopérateur dans Amazon DocumentDB 5.0 et des clusters élastiques. Les analyses d'index sont prises en charge lorsque le filtre réservé aux requêtes possède un niveau de $elemMatch filtre, mais elles ne sont pas prises en charge si une $elemMatch requête imbriquée est incluse.

$elemMatchforme de requête qui prend en charge les analyses d'index dans Amazon DocumentDB 5.0 :

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

$elemMatchforme de requête qui ne prend pas en charge les analyses d'index dans Amazon DocumentDB 5.0 :

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

Dollar ($) et point (.) dans les noms de champs

Amazon DocumentDB ne permet pas d'interroger les champs préfixés Dollar ($) dans $in, $nin et $all dans les objets imbriqués. Par exemple, la requête suivante n'est pas valide dans Amazon DocumentDB :

coll.find({"field": {"$all": [{ "$a": 1 }]}})

$lookup

Amazon DocumentDB permet d'effectuer des correspondances d'égalité (par exemple, jointure externe gauche) et prend également en charge les sous-requêtes non corrélées, mais ne prend pas en charge les sous-requêtes corrélées.

Utilisation d'un index avec $lookup

Vous pouvez désormais utiliser un index avec l'opérateur $lookup stage. Selon votre cas d'utilisation, il existe plusieurs algorithmes d'indexation que vous pouvez utiliser pour optimiser les performances. Cette section explique les différents algorithmes d'indexation $lookup et vous aide à choisir celui qui convient le mieux à votre charge de travail.

Par défaut, Amazon DocumentDB utilise l'algorithme de hachage lorsqu'il allowDiskUse:false est utilisé et la fusion de tri lorsqu'il allowDiskUse:true est utilisé.

Note

L'allowDiskUseoption n'est actuellement pas prise en charge pour la find commande. L'option n'est prise en charge que dans le cadre de l'agrégation. Nous vous recommandons d'utiliser le cadre d'agrégation allowDiskUse:true pour gérer les requêtes volumineuses susceptibles de dépasser les limites de mémoire.

Dans certains cas d'utilisation, il peut être souhaitable de forcer l'optimiseur de requêtes à utiliser un algorithme différent. Vous trouverez ci-dessous les différents algorithmes d'indexation que l'opérateur d'$lookupagrégation peut utiliser :

  • Boucle imbriquée : un plan de boucle imbriquée est généralement avantageux pour une charge de travail si la collection étrangère est inférieure à 1 Go et si le champ de la collection étrangère possède un index. Si l'algorithme de boucle imbriquée est utilisé, le plan d'explication indiquera la scène sous NESTED_LOOP_LOOKUP la forme.

  • Fusion de tri : un plan de fusion de tri est généralement avantageux pour une charge de travail si la collection étrangère ne possède pas d'index sur le champ utilisé pour la recherche et si le jeu de données de travail ne tient pas dans la mémoire. Si l'algorithme de fusion de tri est utilisé, le plan d'explication indiquera l'étape sous la formeSORT_LOOKUP.

  • Hachage : un plan de hachage est généralement avantageux pour une charge de travail si la collection étrangère est inférieure à 1 Go et si le jeu de données de travail est conservé en mémoire. Si l'algorithme de hachage est utilisé, le plan d'explication indiquera l'étape sous HASH_LOOKUP la forme.

Vous pouvez identifier l'algorithme d'indexation utilisé pour l'$lookupopérateur en utilisant explain la requête. Voici un exemple :

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 }

Au lieu d'utiliser la explain() méthode, vous pouvez utiliser le profileur pour examiner l'algorithme utilisé lors de votre utilisation de l'$lookupopérateur. Pour plus d'informations sur le profileur, veuillez consulterProfilage des opérations Amazon DocumentDB.

Utilisation d'un planHint

Si vous souhaitez forcer l'optimiseur de requêtes à utiliser un algorithme d'indexation différent$lookup, vous pouvez utiliser un. planHint Pour ce faire, utilisez le commentaire dans les options de la phase d'agrégation pour forcer un plan différent. Voici un exemple de syntaxe du commentaire :

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

Vous trouverez ci-dessous un exemple d'utilisation de planHint pour forcer l'optimiseur de requêtes à utiliser l'algorithme d'HASHindexation :

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

Pour tester l'algorithme le mieux adapté à votre charge de travail, vous pouvez utiliser le executionStats paramètre de la explain méthode pour mesurer le temps d'exécution de l'$lookupétape tout en modifiant l'algorithme d'indexation (c'est-à-direHASH/SORT/NESTED_LOOP).

L'exemple suivant montre comment mesurer le temps executionStats d'exécution de l'$lookupétape à l'aide de l'SORTalgorithme.

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

$naturalet tri inversé

Amazon DocumentDB prend uniquement en charge $natural les scans de collecte transférés. Les scans de collecte inversés ({$natural: -1}) conduiront à unMongoServerError.