MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Come determinare se $addToSet ha effettivamente aggiunto un nuovo elemento in un documento MongoDB o se l'elemento esisteva già?

Ovviamente quello che stai facendo qui è in realtà controllare la risposta che indica se un documento è stato aggiornato o inserito o in effetti se nessuna delle due operazioni è avvenuta. Questo è il tuo miglior indicatore per un $addToSet per aver eseguito un aggiornamento il documento verrebbe quindi aggiornato.

Il $addToSet l'operatore stesso non può produrre duplicati, questa è la natura dell'operatore. Ma potresti davvero avere dei problemi con la tua logica:

{                                                
      "$addToSet", new BsonDocument()
           {
                { "items", new BsonDocument()
                     {
                          { "id", item.Id },
                          { "v", item.Value } 
                     }
                }
           }
 }

Quindi chiaramente stai mostrando che un elemento nel tuo "set" è composto da due campi, quindi se quel contenuto varia in qualche modo (cioè lo stesso ID ma valore diverso) allora l'oggetto è in realtà un membro "unico" del set e lo farà essere aggiunti. Non ci sarebbe modo, ad esempio, per il $addToSet operatore per non aggiungere nuovi valori basati esclusivamente sull'"id" come identificatore univoco. Dovresti effettivamente eseguirlo nel codice.

Una seconda possibilità qui per una forma di duplicato è che la parte della tua query non trovi correttamente il documento che deve essere aggiornato. Il risultato sarebbe la creazione di un nuovo documento che contiene solo il membro appena specificato nel "set". Quindi un errore di utilizzo comune è qualcosa del genere:

db.collection.update(
    { 
        "id": ABC,
        "items": { "$elemMatch": {
            "id": 123, "v": 10
         }},
    {
        "$addToSet": {
            "items": {
                "id": 123, "v": 10
            }
        }
    },
    { "upsert": true }
)

Il risultato di quel tipo di operazione creerebbe sempre un nuovo documento perché il documento esistente non conteneva l'elemento specificato nel "set". L'implementazione corretta è non verificare la presenza del membro "set" e consentire $addToSet per fare il lavoro.

Se davvero hai vero voci duplicate che si verificano nel "set" in cui tutti gli elementi del documento secondario sono esattamente gli stessi, quindi è stato causato da qualche altro codice presente o passato.

Se sei sicuro che vengano create nuove voci, cerca nel codice le istanze di $push o in effetti e la manipolazione dell'array nel codice che sembra agire sullo stesso campo.

Ma se stai usando correttamente l'operatore allora $addToSet fa esattamente quello che deve fare.