Reputation: 7746
I need to update a MongoDB document that looks like this:
{
"_id" : ObjectId("A"),
"participant" : "John Doe",
"roles" : [{
"roleId" : ObjectId("AA"),
"responsibilities" : [{
"_id" : ObjectID("AAA"),
"name" : "resp 1"
}, {
"_id" : ObjectID("AAB"),
"name" : "resp 2"
}]
}, {
"roleId" : ObjectId("AB"),
"responsibilities" : []
}]
}
The updates come in two forms:
{ "roleId" : ObjectId("AC"), "responsibilities" : [] }
Upvotes: 0
Views: 337
Reputation: 1238
Your first update:
db.getCollection('collection').update({},
{
$pull: {
'roles': {
'responsibilities': {$size: 0}
}
}
}, {multi: true})
Basically, removes element of any (this is where multi: true comes in) "roles" array with "responsibilities" being an empty array (or size 0)
Your second update, assuming a "new role" is a role with an empty responsibilities array:
db.getCollection('collection').update(
{
'roles': {
$not: {
$elemMatch: {
'roleId': ObjectId("AC")
}
}
}
},
{
$push: {
'roles': {
'roleId': ObjectId("AC"),
'responsibilities' : []
}
}
}, {multi: true})
Finds documents that don't have a roles array where an element has an empty responsibilities array, and then pushes a new role with a new ObjectId, or you can specify one yourself.
I've tested this on a small collection of 5 documents and seems to work, let me know if you need any clarification or if it does not work.
It's worth noting that querying an array where you have to iterate through the array $elemMatch is what you're looking for. When modifying and you need to iterate through an array $pull is what you want to use.
Upvotes: 1