Mes collègues et moi avons trouvé une solution de contournement. Nous pouvons l'appeler initialisation en trois étapes .
Rappelons que MongoDB garantit l'atomicité des opérations sur un seul document. Avec ce fait à l'esprit, nous pouvons fonctionner de la manière suivante :
- Essayez de mettre à jour le document, en incrémentant correctement les compteurs à un intervalle de temps spécifié. Ne faites aucun upsert, juste une opération de mise à jour à l'ancienne. N'oubliez pas que l'exécution d'une instruction de mise à jour renvoie le nombre de documents écrits. Si le nombre de documents rédigés est supérieur à zéro, vous avez terminé.
- Si le nombre de documents écrits par la mise à jour est nul, cela signifie que le document relatif à mettre à jour n'est pas encore présent dans la collection. Essayez d'insérer le document entier pour les balises spécifiées. Mettez tous les compteurs (valeurs des champs) à zéro. De plus, l'exécution d'une instruction d'insertion renvoie le nombre de documents écrits. S'il renvoie zéro ou lève une exception, peu importe :cela signifie qu'un autre processus a déjà inséré le document pour les mêmes balises.
- Exécutez à nouveau la même mise à jour ci-dessus.
Le code devrait ressembler à quelque chose de similaire à l'extrait de code suivant.
// Firt of all, try the update
var result = db.test.update(
{timestamp_minute: ISODate("2013-10-10T23:06:00.000Z"), type: “memory_used”},
{$inc: {"values.39": 1}},
{upsert: false}
);
// If the update do not succeed, then try to insert the document
if (result.nModified === 0) {
try {
db.test.insert(/* Put here the whole document */);
} catch (err) {
console.log(err);
}
// Here we are sure that the document exists.
// Retry to execute the update statement
db.test.update(/* Same update as above */);
}
La procédure ci-dessus fonctionne si une condition préalable est remplie :_id
La valeur doit être dérivée d'autres champs du document. Dans notre exemple, _id
la valeur serait '2013-10-10T23:06:00.000Z-memory_used
. En utilisant uniquement cette technique, l'insertion au point 2. échouera correctement.