Differenze funzionali: Amazon DocumentDB e MongoDB - Amazon DocumentDB

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Differenze funzionali: Amazon DocumentDB e MongoDB

Di seguito sono riportate le differenze funzionali tra Amazon DocumentDB (con compatibilità con MongoDB) e MongoDB.

Vantaggi funzionali di Amazon DocumentDB

Transazioni implicite

In Amazon DocumentDB, tutte le CRUD istruzioni (findAndModify,, updateinsert,delete) garantiscono atomicità e coerenza, anche per le operazioni che modificano più documenti. Con il lancio di Amazon DocumentDB 4.0, sono ora supportate le transazioni esplicite che forniscono ACID proprietà per operazioni con più istruzioni e raccolte multiple. Per ulteriori informazioni sull'utilizzo delle transazioni in Amazon DocumentDB, consulta. Transazioni in Amazon DocumentDB

Di seguito sono riportati alcuni esempi di operazioni in Amazon DocumentDB che modificano più documenti che soddisfano comportamenti sia atomici che coerenti.

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

Le singole operazioni che compongono operazioni di massa come updateMany e deleteMany sono atomiche, ma la totalità dell'operazione di massa non è atomica. Ad esempio, la totalità dell'operazione insertMany è atomica se le singole operazioni di inserimento vengono eseguite correttamente senza errori. Se si verifica un errore con un'operazione insertMany, ogni singola istruzione insert all'interno dell'operazione insertMany verrà eseguita come operazione atomica. Se sono necessarie ACID proprietà e deleteMany operazioni insertManyupdateMany, si consiglia di utilizzare una transazione.

Differenze funzionali aggiornate

Amazon DocumentDB continua a migliorare la compatibilità con MongoDB sfruttando a ritroso le funzionalità che i nostri clienti ci chiedono di sviluppare. Questa sezione contiene le differenze funzionali che abbiamo rimosso in Amazon DocumentDB per semplificare le migrazioni e la creazione di applicazioni per i nostri clienti.

Indicizzazione degli array

A partire dal 23 aprile 2020, Amazon DocumentDB ora supporta la capacità di indicizzare array di dimensioni superiori a 2.048 byte. Il limite per un singolo elemento in un array rimane comunque di 2.048 byte, il che è coerente con MongoDB.

Se si sta creando un nuovo indice, non è necessaria alcuna operazione per sfruttare le funzionalità migliorate. Se si dispone di un indice esistente, è possibile sfruttare le funzionalità migliorate rilasciando l'indice e quindi ricreandolo. La versione dell'indice corrente con le funzionalità migliorate è "v" : 3.

Nota

Per i cluster di produzione, il rilascio dell'indice potrebbe influenzare le prestazioni dell'applicazione. Si consiglia di eseguire innanzitutto una verifica e di procedere con cautela quando si apportano modifiche a un sistema di produzione. Inoltre, il tempo necessario per ricreare l'indice sarà una funzione della dimensione complessiva dei dati della raccolta.

È possibile eseguire una query per la versione degli indici utilizzando il seguente comando.

db.collection.getIndexes()

L'aspetto dell'output di questa operazione è simile al seguente. In questo output, la versione dell'indice è "v" : 3, che è quella più recente.

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

Indici a più chiavi

A partire dal 23 aprile 2020, Amazon DocumentDB ora supporta la possibilità di creare un indice composto con più chiavi nello stesso array.

Se si sta creando un nuovo indice, non è necessaria alcuna operazione per sfruttare le funzionalità migliorate. Se si dispone di un indice esistente, è possibile sfruttare le funzionalità migliorate rilasciando l'indice e quindi ricreandolo. La versione dell'indice corrente con le funzionalità migliorate è "v" : 3.

Nota

Per i cluster di produzione, il rilascio dell'indice potrebbe influenzare le prestazioni dell'applicazione. Si consiglia di eseguire innanzitutto una verifica e di procedere con cautela quando si apportano modifiche a un sistema di produzione. Inoltre, il tempo necessario per ricreare l'indice sarà una funzione della dimensione complessiva dei dati della raccolta.

È possibile eseguire una query per la versione degli indici utilizzando il seguente comando.

db.collection.getIndexes()

L'aspetto dell'output di questa operazione è simile al seguente. In questo output, la versione dell'indice è "v" : 3, che è quella più recente.

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

Caratteri nulli nelle stringhe

A partire dal 22 giugno 2020, Amazon DocumentDB ora supporta i caratteri null ('\0') nelle stringhe.

Controllo degli accessi basato sui ruoli

A partire dal 26 marzo 2020, Amazon DocumentDB supporta il controllo degli accessi basato sui ruoli (RBAC) per i ruoli integrati. Per ulteriori informazioni, consulta Controllo accessi basato sui ruoli.

$regexindicizzazione

A partire dal 22 giugno 2020, Amazon DocumentDB ora supporta la possibilità per $regex gli operatori di utilizzare un indice.

Per utilizzare un indice con l'operatore $regex, è necessario utilizzare il comando hint(). Quando si utilizza hint(), è necessario specificare il nome del campo in cui si sta applicando $regex. Ad esempio, se si dispone di un indice nel campo product con il nome dell'indice come p_1, db.foo.find({product: /^x.*/}).hint({product:1}) utilizzerà l'indice p_1, ma db.foo.find({product: /^x.*/}).hint(“p_1”) non utilizzerà l'indice. È possibile verificare se viene scelto un indice utilizzando il comando explain() o utilizzando il profiler per la registrazione di query lente. Ad esempio db.foo.find({product: /^x.*/}).hint(“p_1”).explain().

Nota

Il metodo hint() può essere utilizzato solo con un indice alla volta.

L'utilizzo di un indice per una query $regex è ottimizzato per le query regex che utilizzano un prefisso e non specificano le opzioni regex I, m o o.

Quando si utilizza un indice con $regex, si consiglia di creare un indice in campi altamente selettivi in cui il numero di valori duplicati è inferiore all'1% del numero totale di documenti nella raccolta. Ad esempio, se la raccolta contiene 100.000 documenti, creare solo indici nei campi in cui lo stesso valore si verifica al massimo 1000 volte.

Proiezione per documenti annidati

Esiste una differenza funzionale con $project l'operatore tra Amazon DocumentDB e MongoDB nella versione 3.6 che è stata risolta in Amazon DocumentDB 4.0 ma non sarà supportata in Amazon DocumentDB 3.6.

Amazon DocumentDB 3.6 considera solo il primo campo di un documento annidato quando applica una proiezione, mentre MongoDB 3.6 analizzerà i documenti secondari e applicherà la proiezione anche a ciascun documento secondario.

Ad esempio: se la proiezione è“a.b.c”: 1, il comportamento funziona come previsto sia in Amazon DocumentDB che in MongoDB. Tuttavia, se la proiezione è{a:{b:{c:1}}}, Amazon DocumentDB 3.6 applicherà la proiezione a solo a e non a o. b c In Amazon DocumentDB 4.0, la proiezione {a:{b:{c:1}}} verrà applicata aa, b e. c

Differenze funzionali con MongoDB

Amazon DocumentDB non supporta $vectorSearch come operatore indipendente. Supportiamo invece, vectorSearch all'interno dell'$searchoperatore. Per ulteriori informazioni, consulta Ricerca vettoriale per Amazon DocumentDB.

OpCountersCommand

Il OpCountersCommand comportamento di Amazon DocumentDB si discosta da quello di MongoDB nel modo seguente: opcounters.command

  • MongoDB opcounters.command conta tutti i comandi tranne inserimento, aggiornamento ed eliminazione, mentre Amazon DocumentDB esclude OpCountersCommand anche il comando. find

  • Amazon DocumentDB conta alcuni comandi interni per il. OpCountersCommand

Database e raccolte di amministrazione

Amazon DocumentDB non supporta rispettivamente l'amministratore o il database locale né MongoDB o le raccolte. system.* startup_log

cursormaxTimeMS

In Amazon DocumentDB, cursor.maxTimeMS reimposta il contatore per ogni richiesta. getMore Pertanto, se maxTimeMS viene specificato un valore di 3000 MS, la query impiega 2800 MS e ogni getMore richiesta successiva impiega 300 MS, quindi il cursore non scadrà. Il cursore scade solo quando una singola operazione, la query o una singola richiesta, richiede più di quanto specificato. getMore maxTimeMS Inoltre, lo sweeper che controlla il tempo di esecuzione del cursore viene eseguito con una granularità di cinque (5) minuti.

explain()

Amazon DocumentDB emula MongoDB 4.0 API su un motore di database appositamente progettato che utilizza un sistema di storage distribuito, con tolleranza ai guasti e riparazione automatica. Di conseguenza, i piani di interrogazione e l'output di explain() possono differire tra Amazon DocumentDB e MongoDB. I clienti che desiderano il controllo sul piano di query possono utilizzare l'operatore $hint per applicare la selezione di un indice preferito.

Restrizioni sui nomi dei campi

Amazon DocumentDB non supporta i punti «.» nel nome del campo di un documento, ad esempio,. db.foo.insert({‘x.1’:1})

Amazon DocumentDB inoltre non supporta il prefisso $ nei nomi dei campi.

Ad esempio, prova il seguente comando in Amazon DocumentDB o MongoDB:

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

MongoDB restituirà quanto segue:

WriteResult({ "nInserted" : 1 })

Amazon DocumentDB restituirà un errore:

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

Esiste un'eccezione a questa differenza funzionale. I seguenti nomi di campo che iniziano con il prefisso $ sono stati inseriti nella whitelist e possono essere utilizzati con successo in Amazon DocumentDB: $id, $ref e $db.

Compilazioni dell'indice

Amazon DocumentDB consente la creazione di un solo indice alla volta su una raccolta. In primo piano o sullo sfondo. Se operazioni come createIndex() o dropIndex() si verificano nella stessa raccolta quando è in corso una creazione di indice, l'operazione appena tentata avrà esito negativo.

Per impostazione predefinita, le compilazioni degli indici in Amazon DocumentDB e MongoDB versione 4.0 vengono eseguite in background. MongoDB versione 4.2 e successive ignorano l'opzione di creazione dell'indice in background se specificata o i relativi createIndexes helper della shell e. createIndex() createIndexes()

Un indice Time to Live (TTL) inizia a far scadere i documenti dopo il completamento della creazione dell'indice.

Ricerca con chiave vuota nel percorso

Quando cerchi una chiave che include una stringa vuota come parte del percorso (ad esempio x.x..b) e l'oggetto ha un percorso chiave di stringa vuoto (ad esempio{"x" : [ { "" : 10 }, { "b" : 20 } ]}) all'interno di un array, Amazon DocumentDB restituirà risultati diversi rispetto a quelli che si otterrebbero eseguendo la stessa ricerca in MongoDB.

In MongoDB, la ricerca del percorso della chiave vuota all'interno dell'array funziona come previsto quando la chiave stringa vuota non si trova alla fine della ricerca del percorso. Tuttavia, quando la chiave stringa vuota si trova alla fine della ricerca del percorso, non esamina l'array.

Tuttavia, in Amazon DocumentDB, viene letto solo il primo elemento all'interno dell'array, perché getArrayIndexFromKeyString converte una stringa vuota in0, quindi la ricerca della chiave di stringa viene considerata come una ricerca dell'indice dell'array.

APIsMongoDB, operazioni e tipi di dati

Amazon DocumentDB è compatibile con MongoDB 3.6 e 4.0. APIs Per un up-to-date elenco delle funzionalità supportate, consulta. APIsMongoDB, operazioni e tipi di dati supportati in Amazon DocumentDB

mongodumpe mongorestore utilità

Amazon DocumentDB non supporta un database di amministrazione e quindi non esegue il dump o il ripristino del database di amministrazione quando si utilizzano le mongodump utilità or. mongorestore Quando crei un nuovo database in Amazon DocumentDB utilizzandomongorestore, devi ricreare i ruoli utente oltre all'operazione di ripristino.

Nota

Consigliamo MongoDB Database Tools fino alla versione 100.6.1 inclusa per Amazon DocumentDB. Puoi accedere ai download di MongoDB Database Tools qui.

Ordinamento dei risultati

Amazon DocumentDB non garantisce l'ordinamento implicito dei set di risultati. Per garantire l'ordinamento di un set di risultati, specifica in modo esplicito un ordinamento utilizzando sort().

L'esempio seguente ordina gli elementi della raccolta dell'inventario in ordine decrescente in base al campo del magazzino.

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

Quando si utilizza la fase di $sort aggregazione, l'ordinamento non viene mantenuto a meno che la $sort fase non sia l'ultima fase della pipeline di aggregazione. Quando si utilizza la fase di $sort aggregazione in combinazione con la fase di $group aggregazione, la fase di $sort aggregazione viene applicata solo agli accumulatori e. $first $last In Amazon DocumentDB 4.0, è stato aggiunto il supporto $push per rispettare l'ordinamento della fase precedente$sort.

Scritture riutilizzabili

A partire dai driver compatibili MongoDB 4.2, le scritture ripetibili sono abilitate per impostazione predefinita. Tuttavia, Amazon DocumentDB attualmente non supporta scritture riutilizzabili. La differenza funzionale si manifesterà in un messaggio di errore simile al seguente.

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

Le scritture riutilizzabili possono essere disabilitate tramite la stringa di connessione (ad esempio) MongoClient("mongodb://my.mongodb.cluster/db?retryWrites=false")) o l'argomento della parola chiave del MongoClient costruttore (ad esempio,. MongoClient("mongodb://my.mongodb.cluster/db", retryWrites=False))

Di seguito è riportato un esempio Python che disabilita le scritture ripetibili nella stringa di connessione.

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)

Indice Sparse

Per utilizzare un indice Sparse creato in una query, devi utilizzare la clausola $exists nei campi che coprono l'indice. Se ometti$exists, Amazon DocumentDB non utilizza l'indice sparso.

Di seguito è riportato un esempio.

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

Per gli indici sparsi e a più chiavi, Amazon DocumentDB non supporta un vincolo di chiave univoco se la ricerca di un documento produce un insieme di valori e manca solo un sottoinsieme dei campi indicizzati. Ad esempio, createIndex({"a.b" : 1 }, { unique : true, sparse :true }) non è supportato, dato che l'input di "a" : [ { "b" : 2 }, { "c" : 1 } ], come "a.c" è memorizzato nell'indice.

$allUtilizzo all'$elemMatchinterno di un'espressione

Amazon DocumentDB attualmente non supporta l'uso dell'$elemMatchoperatore all'interno di un'$allespressione. Come soluzione alternativa, è possibile utilizzare l'operatore $and con $elemMatch come segue.

Funzionamento originale:

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

Funzionamento aggiornato:

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

$ne,$nin,$nor, $not$exists, e indicizzazione $elemMatch

Amazon DocumentDB attualmente non supporta la possibilità di utilizzare gli indici con gli operatori$ne,,, $nin $nor$not, $exists e. $distinct Di conseguenza, l'utilizzo di questi operatori comporterà scansioni delle raccolte. L'esecuzione di un filtro o di una corrispondenza prima di utilizzare uno di questi operatori ridurrà la quantità di dati da scansionare e quindi potrà migliorare le prestazioni.

Amazon DocumentDB ha aggiunto il supporto per le scansioni degli indici con l'$elemMatchoperatore in Amazon DocumentDB 5.0 e cluster elastici. Le scansioni degli indici sono supportate quando il solo filtro di interrogazione ha un livello del $elemMatch filtro, ma non sono supportate se è inclusa una query annidata. $elemMatch

$elemMatchforma di query che supporta le scansioni degli indici in Amazon DocumentDB 5.0:

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

$elemMatchforma di query che non supporta le scansioni degli indici in Amazon DocumentDB 5.0:

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

$lookup

Amazon DocumentDB supporta la possibilità di eseguire corrispondenze di uguaglianza (ad esempio, left outer join) e supporta anche sottoquery non correlate, ma non supporta sottoquery correlate.

Utilizzo di un indice con $lookup

Ora puoi utilizzare un indice con lo $lookup stage operator. In base al caso d'uso, sono disponibili diversi algoritmi di indicizzazione che è possibile utilizzare per ottimizzare le prestazioni. Questa sezione spiegherà i diversi algoritmi di indicizzazione $lookup e ti aiuterà a scegliere quello migliore per il tuo carico di lavoro.

Per impostazione predefinita, Amazon DocumentDB utilizza l'algoritmo hash quando allowDiskUse:false viene utilizzato e sort merge quando viene utilizzato. allowDiskUse:true In alcuni casi d'uso, può essere consigliabile forzare l'ottimizzatore di query a utilizzare un algoritmo diverso. Di seguito sono riportati i diversi algoritmi di indicizzazione che l'operatore di $lookup aggregazione può utilizzare:

  • Ciclo annidato: un piano a ciclo annidato è in genere utile per un carico di lavoro se la raccolta esterna è <1 GB e il campo della raccolta esterna ha un indice. Se viene utilizzato l'algoritmo a ciclo annidato, il piano di spiegazione mostrerà lo stage come. NESTED_LOOP_LOOKUP

  • Ordinamento e unione: un piano di ordinamento e unione è in genere utile per un carico di lavoro se la raccolta esterna non dispone di un indice sul campo utilizzato nella ricerca e il set di dati di lavoro non si adatta alla memoria. Se viene utilizzato l'algoritmo di ordinamento e unione, il piano di spiegazione mostrerà lo stage come. SORT_LOOKUP

  • Hash: un piano hash è in genere utile per un carico di lavoro se la raccolta esterna è < 1 GB e il set di dati di lavoro si adatta alla memoria. Se viene utilizzato l'algoritmo hash, il piano di spiegazione mostrerà lo stage come. HASH_LOOKUP

È possibile identificare l'algoritmo di indicizzazione utilizzato per l'$lookupoperatore utilizzando explain nella query. Di seguito è riportato un esempio.

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 }

In alternativa all'utilizzo del explain() metodo, è possibile utilizzare il profiler per esaminare l'algoritmo utilizzato con l'utilizzo dell'$lookupoperatore. Per ulteriori informazioni sul profiler, consulta. Profilazione delle operazioni di Amazon DocumentDB

Utilizzo di un planHint

Se desideri forzare l'ottimizzatore di query a utilizzare un algoritmo di indicizzazione diverso con$lookup, puoi usare un. planHint Per fare ciò, usa il commento nelle opzioni della fase di aggregazione per forzare un piano diverso. Di seguito è riportato un esempio della sintassi del commento:

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

Di seguito è riportato un esempio di utilizzo di planHint per forzare l'ottimizzatore di query a utilizzare l'algoritmo di HASH indicizzazione:

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

Per verificare qual è l'algoritmo più adatto al proprio carico di lavoro, è possibile utilizzare il executionStats parametro del explain metodo per misurare il tempo di esecuzione della $lookup fase mentre si modifica l'algoritmo di indicizzazione (ad esempio,//). HASH SORT NESTED_LOOP

L'esempio seguente mostra come misurare il tempo executionStats di esecuzione dello $lookup stadio utilizzando l'algoritmo. SORT

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