Qual è la differenza tra findAndModify e l'aggiornamento in MongoDB?


175

Sono un po 'confuso dal findAndModifymetodo in MongoDB. Qual è il vantaggio rispetto al updatemetodo? Per me, sembra che restituisca solo l'oggetto prima e poi lo aggiorni. Ma perché devo prima restituire l'articolo? Ho letto MongoDB: la guida definitiva e dice che è utile per manipolare le code ed eseguire altre operazioni che richiedono l'atomicità in stile get-and-set. Ma non capivo come ci riuscisse. Qualcuno può spiegarmelo?

Risposte:


153

Se recuperi un elemento e lo aggiorni, potrebbe esserci un aggiornamento di un altro thread tra questi due passaggi. Se aggiorni prima un elemento e poi lo recuperi, potrebbe esserci un altro aggiornamento nel mezzo e otterrai un elemento diverso da quello che hai aggiornato.

Farlo "in modo atomico" significa che ti viene garantito lo stesso identico oggetto che stai aggiornando, vale a dire che nessuna altra operazione può avvenire nel mezzo.


6
Sono ancora un po 'confuso. In che modo findAndModifygarantisce che non vi siano altre operazioni di aggiornamento che interferiscono con esso?
chaonextdoor,

78
@chaonextdoor findAndModify acquisisce un blocco al database quando avvia l'operazione in modo che nessun'altra operazione possa essere elaborata quando è in esecuzione. Al termine dell'operazione rilascia il blocco.
Lycha,

4
findAndModify non ottiene effettivamente un blocco fino alla modifica della parte della richiesta. Pertanto è possibile che più processi siano in grado di aggiornare lo stesso record.
Mark Unsworth,

5
@MarkUnsworth apre un caso di supporto con 10gen - se c'è un bug nel blocco con findAndModify, posso garantire che gli ingegneri vorranno risolverlo al più presto. Se così fosse, vedremmo molte persone segnalare questo comportamento, ma findAndModify funziona come progettato per praticamente tutti coloro che lo usano - casi in cui sembrava che non dipendesse da errori logici o di implementazione sul lato client , ma ovviamente in software complessi può esserci sempre un bug.
Asya Kamsky il

4
@AsyaKamsky Stavo pensando di discutere con te, ma poi ho capito che hai ragione, quindi ora sto pensando che dovrei scusarmi. Scusa!
funkyeah,

54

findAndModify restituisce il documento, l'aggiornamento no.

Se ho capito correttamente Dwight Merriman (uno degli autori originali di mongoDB), usare l'aggiornamento per modificare un singolo documento, ad esempio ("multi": false} è anche atomico. Attualmente, dovrebbe anche essere più veloce rispetto a fare l'aggiornamento equivalente usando findAndModify.


31

Dai documenti MongoDB (enfasi aggiunta):

  • Per impostazione predefinita, entrambe le operazioni modificano un singolo documento. Tuttavia, il metodo update () con la sua multi opzione può modificare più di un documento .

  • Se più documenti corrispondono ai criteri di aggiornamento, per findAndModify (), è possibile specificare un ordinamento per fornire un certo controllo su quale documento aggiornare. Con il comportamento predefinito del metodo update (), non è possibile specificare quale documento singolo aggiornare quando più documenti corrispondono.

  • Per impostazione predefinita, il metodo findAndModify () restituisce la versione pre-modificata del documento . Per ottenere il documento aggiornato, utilizzare la nuova opzione. Il metodo update () restituisce un oggetto WriteResult che contiene lo stato dell'operazione. Per restituire il documento aggiornato, utilizzare il metodo find (). Tuttavia, altri aggiornamenti potrebbero aver modificato il documento tra l'aggiornamento e il recupero del documento. Inoltre, se l'aggiornamento ha modificato solo un singolo documento ma sono stati trovati più documenti corrispondenti, sarà necessario utilizzare una logica aggiuntiva per identificare il documento aggiornato.

  • Prima di MongoDB 3.2 non è possibile specificare un problema di scrittura per findAndModify () per sovrascrivere il problema di scrittura predefinito, mentre è possibile specificare un problema di scrittura nel metodo update () da MongoDB 2.6.

Quando si modifica un singolo documento, sia findAndModify () che il metodo update () aggiornano atomicamente il documento.


1
È sempre possibile specificare la preoccupazione di scrittura per aggiornare l'operazione. Inoltre, dal 3.2 (3.1.1 tecnicamente) è possibile specificare anche la preoccupazione di scrittura per findAndModify. jira.mongodb.org/browse/SERVER-6558
Asya Kamsky,

Ho scoperto che in MongDB 3.6, sebbene il documento dichiari findAndModify()per impostazione predefinita solo un documento e update()possa aggiornare uno o più documenti, quando ne uso uno arrayFilters, findAndModify()aggiorna tutte le corrispondenze. Forse è un bug ??
WesternGun

Non ci sono bug: arrayFilters ti consente di aggiornare più elementi dell'array ma sono ancora in un singolo documento.
Asya Kamsky,

10

Un'utile classe di casi d'uso sono i contatori e casi simili. Ad esempio, dai un'occhiata a questo codice (uno dei test MongoDB): find_and_modify4.js .

Pertanto, con findAndModifyte incrementa il contatore e ottieni il suo valore incrementato in un solo passaggio. Confronta: se (A) esegui questa operazione in due passaggi e qualcun altro (B) esegue la stessa operazione tra i tuoi passaggi, A e B possono ottenere lo stesso valore del contatore precedente anziché due diversi (solo un esempio di possibili problemi).


0

Abbiamo usato findAndModify () per operazioni Counter (inc o dec) e altri casi mutati di singoli campi. Durante la migrazione della nostra applicazione da Couchbase a MongoDB, ho trovato questa API per sostituire il codice che esegue GetAndlock (), modificare il contenuto localmente, sostituire () per salvare e Get () di nuovo per recuperare il documento aggiornato. Con mongoDB, ho appena usato questa singola API che restituisce il documento aggiornato.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.