pymongo之find_one_and_update原子性操作(管道操作)
为什么要使用原子性操作
众所周知大家在面临高并发的时候操作数据库需要确保数据的原子性,为什么要确保数据的原子性呢,因为如果不确保数据的原子性就会出现脏读,脏写
的现象,这些现象会导致数据库里面的数据变得更加混乱,我在使用mongodb的find_one_and_update的时候遇到了一些比较尴尬的问题,就是在查询的时候
某些字段是不能当作查询条件的,但是在做更新或写入操作的时候这些字段又要更具不同的判断条件去写入不同的值,所以这时候就陷入一个很大的问题,
find_one_and_update提供的逻辑运算符中是没有if判断的,但是不巧的是mongodb 官方给find_ond_and_update 提高了聚合的管道操作,这就使得
find_one_and_update 可以使用聚合查询的运算符,但是官方文档并没有给出一个详细的操作案例,下面的代码是使用find_one_and_update操作的时候
使用了if判断来对不同的字段在不同的条件下设置不同的值的操作。
getattr(mg_db_write, 'table_name').find_one_and_update(
{"user_id": user_id, "product_id": product_id, "appid": appid, "valid": True},
[{
"$set":{
"earn_end_time":{
"$cond":
[
{"$gt":
[
get_datetime_last_day(),
{"$add": ["$earn_end_time",30*24*60*60]}
]
}, get_datetime_last_day(), {"$add": ["$earn_end_time",30*24*60*60]}
]
},
"redeemed_bonus_count":{
"$cond":[
{
"$ifNull":["$redeemed_bonus_count",None]
},{"$add": ["$redeemed_bonus_count",0]},0
]
},
"create_time":{
"$cond":[
{
"$ifNull":["$create_time",None]
},"$create_time",get_now_datetime()
]
},
"earn_bonus_count":{
"$cond":[
{
"$ifNull":["$earn_bonus_count",None]
},{"$add": ["$earn_bonus_count",earn_bonus_count]},earn_bonus_count
]
},
},
},
],
upsert = True
)