I'm trying to update my collection
For the single, object need to update the status and updated time.
Input object id as id
new status as current status
Condition If the new status
is different from the status
in DB, then need to $push
new status
and timestamp
into activity_log
array. And update the update the updated_time
and status
of the record.
If the new status
and previous status is same then updated_time
will be updated.
Is it possible to do that in pymongo using single update?
collection.update({
'_id': ObjectId(id),
}, {
'$cond': {
'if': {
'status': {
'$ne': current_status
}
},
'then': {
'$push': {
'activity_log': {
'status': current_status,
'changed_time': datetime.now()
}
}
},
'else': None
},
'$set': {
'status': current_status,
'updated_time': datetime.now()
}
})
You can do that in a single query, From MongoDB 4.2 update query supports aggregation pipeline , You can do that as per below code
collection.update(
{'_id': ObjectId(id)},
[{'$set': {
'status': current_status,
'updated_time': datetime.now(),
'activity_log':{
'$cond': {
'if': {'$ne': ['$status',current_status]},
'then': {$concatArrays:['$activity_log',[
{
'status': current_status,
'changed_time': datetime.now()
}
]]},
'else': '$activity_log'
}
}}}]
)
The $cond
operator is not flow control like if-then-else, it is an expression that returns a value.
If you want to conditionally update a field based on the value of another field in the same document, you can use the pipeline form of update, assigning the field the result of the $cond
expression.
collection.update(
{'_id': ObjectId(id)},
[{'$set': {
'status': current_status,
'updated_time': datetime.now(),
'activity_log':{
'$cond': {
'if': {'$ne': ['$status',current_status]}
'then': {$concatArrays:['$activity_log',[
{
'status': current_status,
'changed_time': datetime.now()
}
]]},
'else': '$activity_log'
}
}}]
)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.