Assigning a field value to another field in a document

I have created a mongodb collection in python django.The collection name is audit_details and it consists of following data

_id:630e026211cb34947c85a7a5
user:"akhil"
status:null
old_data:null
new_data:2022-08-30T17:58:18.551+00:00


_id:630e026211cb34947c85a7a6
user:"sandeep"
status:null
old_data:null
new_data:2022-08-30T17:58:18.551+00:00

now,i want the new_data value to be assigned to “old_data” and the “new_data” will take the “updated_time” value taken from API post request(I am using django restframework and the data i am sending as post request is {“action”:“modify”,“user”:"sandeep,“updated_time”:“2022-08-26 16:26:00”})

i want the output to be like below

_id:630e026211cb34947c85a7a6
user:"sandeep"
status:modified
old_data:migration was scheduled at 2022-08-30T17:58:18.551+00:00
new_data:migration now scheduled at "2022-08-26 16:26:00"

I have tried the following:

    audit_details.update_many({ "user": "sandeep" },
   {
     "$currentDate": {
        "last_modified": True,
     },
     "$set": {
        "status": "modified",
         "old_data": {"$concat":["Migration Task was scheduled at ", "$new_data"]},
         "new_data" : {"$concat": ["Migration Task now scheduled at ",  request.data['updated_time']]}


     }

     }

)

my output is like below,which is not correct:

{
  "_id": {
    "$oid": "630e026211cb34947c85a7a5"
  },
  "user": "sandeep",
  "status": "modified",
  "old_data": {
    "$concat": [
      "Migration Task for",
      "$new_data"
    ]
  },
  "new_data": {
    "$concat": [
      "Migration Task for",
      "2022-08-26 16:26:00"
    ]
  },
  "last_modified": {
    "$date": {
      "$numberLong": "1661917054163"
    }
  }
}

Hi @sai_sankalp and welcome to the community!!

I believe it’s possible to achieve what you need by using the aggregation pipeline as the update operator using update_one, update_many, or find_one_and_update. This feature was added in MongoDB 4.2.

Note that newValue is a list instead of a dictionary, which signifies that this is an aggregation pipeline instead of a simple update document.

Please refer to the documentation for parameters of update query. which explains the same.

As an example, using pymongo:
The query created a filter and the newValue basically contains the aggregation stage which sets the updated values.

filter = { "user": "sandeep" }

newValue = [ { "$set":{"old_data":'$new_data', "new_data": datetime.datetime.now(), "status": "modified"} } ]

collection.update_one(filter, newValue)
 

The output for the above query would look like:

for record in cursor:
   print (record)
{'_id': ObjectId('631982b43831f60dfdcaaee3'), 'user': 'sandeep', 'status': 'modified', 'old_data': datetime.datetime(2022, 9, 8, 11, 19, 19, 356000), 'new_data': datetime.datetime(2022, 9, 8, 11, 55, 0, 291000)}

{'_id': ObjectId('631982c13831f60dfdcaaee4'), 'user': 'akhil', 'status': None, 'old_data': None, 'new_data': datetime.datetime(2022, 9, 8, 11, 19, 37, 149000)}

One suggestion I would like to make from the example you posted is that you might want to rethink the use of a string combined with date datatypes in your new_data and old_data fields. If these two fields are supposed to describe dates, I would recommend you to keep the date datatype, which will make it easier to manipulate in the future.

Please let me know if you have any further questions.

Best Regards
Aasawari

1 Like

Hi @Aasawari
Thanks for the detailed explanation. It was really helpful

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.