À moins de pouvoir tout faire de manière atomique, il existe deux types de conditions existantes pour lesquelles vous souhaitez effectuer un changement, et vous pouvez traiter chacune d'elles de manière atomique :
- aucun enregistrement pour la clé n'existe
- un enregistrement pour la clé existe et son
update_time
est plus ancien quenew_time
Mettre à jour un enregistrement existant pour la clé :
def update_if_stale(key, new_value, new_time):
collection.update({'key': key,
'update_time': {'$lt': new_time}
},
{'$set': {'value': new_value,
'update_time': new_time
}
}
)
Insérer si un enregistrement pour la clé n'existait pas auparavant :
def insert_if_missing(key, new_value, new_time):
collection.update({'key': key},
{'$setOnInsert': {'value': new_value,
'update_time': new_time
}
},
upsert=True
)
($setOnInsert
a été ajouté dans MongoDB 2.4)
Vous pourrez peut-être les regrouper pour obtenir ce dont vous avez besoin, par exemple :
def update_key(key, new_value, new_time):
insert_if_missing(key, new_value, new_time)
update_if_stale(key, new_value, new_time)
Cependant, selon les échelles de temps de suppression/insertion possibles dans votre système, vous pourriez avoir besoin de plusieurs appels (mise à jour/insertion/mise à jour) ou d'autres manigances.
A part :si vous voulez un enregistrement manquant le update_time
champ à traiter comme un enregistrement obsolète à mettre à jour, modifiez {'$lt': new_time}}
à {'$not': {'$gte': new_time}}