View a markdown version of this page

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 (avec compatibilité 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 qui fournissent des propriétés ACID pour les opérations multi-déclarations et multi-collections sont désormais prises en charge. Pour en savoir plus sur l'utilisation des transactions dans Amazon DocumentDB, consultezTransactions dans Amazon DocumentDB.

Voici 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. Si une erreur survient lors d'une insertMany opération, chaque instruction d'insertion individuelle de l'insertManyopération s'exécute comme une opération atomique. Si vous avez besoin de propriétés ACID pour les deleteMany opérations insertManyupdateMany, et, il est recommandé d'utiliser une transaction.

Différences fonctionnelles mises à jour

Amazon DocumentDB continue d'améliorer la compatibilité avec MongoDB en travaillant à rebours à partir des fonctionnalités que nos clients nous demandent de développer. Cette section présente 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 des 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 toujours 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. Testez d'abord et procédez avec prudence lorsque vous apportez des modifications à un système de production. En outre, le temps nécessaire pour recréer l'index dépend 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" } ]

Multi-key index

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. Testez d'abord et procédez avec prudence lorsque vous apportez des modifications à un système de production. En outre, le temps nécessaire pour recréer l'index dépend 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.

Role-based contrôle d'accès

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, veuillez consulter la section Role-Based Contrôle d'accès.

indexation $regex

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 documents imbriqués

Il existe une différence fonctionnelle avec $project l'opérateur entre Amazon DocumentDB et MongoDB dans la version 3.6 qui a été résolue dans Amazon DocumentDB 4.0 mais ne sera 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 l'est“a.b.c”: 1, le comportement fonctionne comme prévu à la fois dans Amazon DocumentDB et MongoDB. Toutefois, si la projection est égale{a:{b:{c:1}}}, Amazon DocumentDB 3.6 appliquera la projection uniquement à a et non à b ouc. Dans Amazon DocumentDB 4.0, la projection {a:{b:{c:1}}} sera appliquée à ab, etc.

Différences fonctionnelles avec MongoDB

Amazon DocumentDB n'est pas pris en charge $vectorSearch en 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 à l'exception de l'insertion, de la mise à jour et de la suppression, tandis que celle d'Amazon DocumentDB exclut OpCountersCommand également la find commande.

  • Amazon DocumentDB compte certaines commandes internes dans leOpCountersCommand.

Bases de données et collections d'administration

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

CursorMaxTimeMS

Dans Amazon DocumentDB, cursor.maxTimeMS réinitialise le compteur pour chaque getMore demande. 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 la durée spécifiéemaxTimeMS. De plus, le balayeur qui vérifie le temps d'exécution du curseur fonctionne avec une granularité de cinq (5) minutes.

explain()

Amazon DocumentDB émule les API MongoDB 3.6, 4.0, 5.0 et 8.0 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éparable. Par conséquent, les plans de requête et la sortie 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é.

Constructions d'index

Amazon DocumentDB n'autorise qu'une seule création d'index sur une collection à la fois. Au premier plan ou à l'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 apparaissent au premier plan. MongoDB version 4.2 et versions ultérieures ignore l'option de génération d'index en 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 } ]}) à l'intérieur d'un tableau, Amazon DocumentDB renvoie des résultats différents de ceux si vous exécutiez la même recherche dans MongoDB.

Dans MongoDB, la recherche de chemin de clé vide dans un 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 ne regarde 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 en0, de sorte que la recherche d'une clé de chaîne est traitée comme une recherche d'index de tableau.

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

Amazon DocumentDB est compatible avec les API MongoDB 3.6, 4.0, 5.0 et 8.0. Pour accéder à la liste à jour des fonctionnalités prises en charge, veuillez consulter API, opérations et types de données MongoDB pris en charge dans Amazon DocumentDB.

utilitaires mongodump et mongorestore

Amazon DocumentDB ne prend pas en charge une base de données d'administration et ne vide ni ne restaure donc la base de données d'administration lors de l'utilisation des mongorestore utilitaires mongodump ou. 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.

Version requise pour les outils de base de données MongoDB

Utilisez les outils de base de données MongoDB jusqu'à la version 100.11.0 incluse pour Amazon DocumentDB. Pour les télécharger, consultez les versions des outils de base de données MongoDB sur le site Web de MongoDB.

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

Lorsque vous utilisez la phase d'$sortagrégation, l'ordre de tri n'est pas préservé, sauf si cette $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'$groupagrégation, la phase d'$sortagrégation n'est appliquée qu'aux $last accumulateurs $first et. Dans Amazon DocumentDB 4.0, la prise en charge du respect de $push l'ordre de tri de l'$sortétape précédente a été ajoutée.

Écrits 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 exempleMongoClient("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 l'omettez$exists, Amazon DocumentDB n'utilisera pas l'index fragmenté.

Voici un exemple.

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

Pour les index fragmentés à plusieurs clés, 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 de $elemMatch dans une expression $all

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

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

Amazon DocumentDB ne prend pas en charge l'interrogation de champs préfixés Dollar ($) dans $in, $nin et $all dans des 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, une 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 de $lookup scène. 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. Utilisez la structure d'agrégation avec 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 en boucle imbriquée est généralement utile 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 affichera l'étape sous NESTED_LOOP_LOOKUP la forme.

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

  • Hash  : un plan de hachage est généralement utile pour une charge de travail si la collection étrangère fait moins de 1 Go et si l'ensemble de données de travail tient en mémoire. Si l'algorithme de hachage est utilisé, le plan d'explication indiquera l'étape commeHASH_LOOKUP.

Vous pouvez identifier l'algorithme d'indexation utilisé pour l'$lookupopérateur à l'aide de explain la requête. Vous trouverez ci-dessous 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 explain() cette 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, consultezProfilage 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 avec$lookup, vous pouvez utiliser un. planHint Pour ce faire, utilisez le commentaire dans les options de la phase d'agrégation pour forcer un autre plan. Vous trouverez ci-dessous un exemple de syntaxe pour le 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 la $lookup phase à l'aide de l'SORTalgorithme.

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

$ tri naturel et inversé

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