But not able to complete the operation successfully
Hi Lavi,
Could you clarify what do you mean by not being able to complete the operation successfully ? If you are getting error messages, could you post them please ?
If I run your update operation on the example data you’ve given, it ran without errors. Perhaps you are looking for a different document outcome, for example if you are wanting to set per_mux_status
field within the same analysis
array element as per_data_status
field in query, like below:
{ "test": "Milan",
"analysis": [
{
"userName": "xxx",
"Status": "SUCCESS",
"startTime": "2016-05-09T18-35-23.601813",
"EndTimes": "2016-05-09T18-40-02.891451",
"analysis_id": "2016-05-09T18-35-23.601813",
"per_data_status"
: [
{ ... },
{ ... }
],
"per_mux_status": {
"id": "9009",
"dir": "9009",
"Status": "SUCCESS",
"StatsSubmission": "DONE",
"ArchiveSubmission": "DONE"
}
}
]
}
You could replace per_mux_status.$
in your update operation with analysis.$.per_mux_status
.
If the above is not what you are looking for, could you provide the following information:
Regards,
Wan.
Hi Lavi,
Currently, as of version v3.2 you won’t able to update nested arrays using $set. There is an open ticket in MongoDB jira tracker SERVER-831 to support $set
for nested arrays, please feel free to watch and/or upvote for updates.
One work-around is to use .forEach to iterate through the arrays and update the document, example:
db.datacomplete.find({
"test":"Milan", "analysis.analysis_id" : "2016-05-09T18-35-23.601813", "analysis.per_data_status.id" : "9009"})
.forEach(
function(doc){
doc.analysis.forEach(function(a){
if(a.analysis_id=="2016-05-09T18-35-23.601813"){
a.per_data_status.forEach(function(data){
if(data.id=="9009"){
data.StatsSubmission = "SUCCESS";
data.ArchiveSubmission = "DONE";
}
})
}
})
db.datacomplete.save(doc)
})
Alternatively, you can modify the document schema to remove nested arrays. For example, depending on your application use case, you could store per_data_status
into another collection. Another example to try is to use sub-document rather than array for analysis
:
{
"_id": ObjectId("57304a006f42802df624aaa6"),
"test": "Milan",
"timestamp": NumberLong("1462781256018"
),
"analysis": {
/* Use username as the key per analysis */
"xxx" : {
"Status": "SUCCESS",
"startTime": "2016-05-09T18-35-23.601813",
"EndTimes": "2016-05-09T18-40-02.891451",
"analysis_id": "2016-05-09T18-35-23.601813",
"per_data_status"
: [
{
"id": "9009",
"dir": "Project_9009",
"Status": "SUCCESS"
,
"StatsSubmission": "SUCCESS",
"ArchiveSubmission": "TODO"
}
]
}
}
}
Different schemas have different benefits depending on your application use case. You may find the following useful:
Also to point out you may want to store the date values as BSON Date via Date(). Especially if you would like to query using date values later on.
Regards,
Wan.
Can someone let me know how to execute mongoDB command inside ppython script? I am using pymongo.
Hi Lavi,
The example below is written using pymongo v3.2 and MongoDB v3.2:
query = {'test': 'Milan',
'analysis.analysis_id': '2016-05-09T18-35-23.601813',
'analysis.per_data_status.id': '9009'}
new_document = collection.find_one(query)
if new_document:
for a in new_document.get('analysis'):
if a.get('analysis_id') == analysis_id:
for d in a.get('per_data_status'):
if d.get('id') == data_status_id:
d['StatsSubmission'] = "DONE"
d['ArchiveSubmission'] = "DONE"
collection.save(new_document)
Depending on the concurrency nature of your application, you may be interested to see Atomicity and Transactions. As mentioned previously, I would recommend to consider your document schema to remove the nested arrays to simplify your database operations.
Also worth mentioning that there is a free online course at MongoDB University to learn more about MongoDB. The next session for working with MongoDB Python Driver - M101P: MongoDB for Developers starts on the 24th May.
Best regards,
Wan.