Query an array of nested documents - node.js

I got this document:
{
"_id" : "111",
"email" : "michael#gmail.com",
"username" : "michael098",
"groups" : [
{
"_id" : "222"
"groupName" : "family",
"groupMembers" : [
{
"_id" : "333"
"name" : "Liam"
},
{
"_id" : "444"
"name" : "Noah"
}
]
},
{
"_id" : "555"
"groupName" : "friends",
"groupMembers" : [
{
"_id" : "666"
"name" : "Oliver"
}
]
}
]
}
I am trying to delete 1 group member by _id, for example if I get userId="111", groupId="222" and groupMemberId="444" the group member with _id="444" will delete.
Example of the document after this delete request:
{
"_id" : "111",
"email" : "michael#gmail.com",
"username" : "michael098",
"groups" : [
{
"_id" : "222"
"groupName" : "family",
"groupMembers" : [
{
"_id" : "333"
"name" : "Liam"
}
]
},
{
"_id" : "555"
"groupName" : "friends",
"groupMembers" : [
{
"_id" : "666"
"name" : "Oliver"
}
]
}
]
}
My attempt (with express and mongoose):
router.delete(
"/:userId/:groupId/:groupMemberId",
catchAsync(async (req, res) => {
const { userId, groupId, groupMemberId } = req.params;
const updatedUser = await User.findByIdAndUpdate(
userId,
{ $pull: { "groups.$.groupMembers": { _id: groupMemberId } } },
{ new: true }
);
res.send({ updatedUser });
})
);
The response from this request: I get an error: “The positional operator did not find the match needed from the query.”

Related

Mongo update to many query

does anyone know how to change a propertie value in mongo
from
i changed JSON.units[0].services[0].label from etiket controle to AuditLabel
i tried this:
db.getCollection('assortiment').updateMany({"units.$[].services.$[].label": "etiket controle"},{ "$set": { "units.$[].services.$[].label": "AuditLabel" }})
but no succes because it dont select anything
{
"_id" : "764",
"meta" : {
"groupsId" : "764",
"type" : "DRYGR"
},
"units" : [
{
"unit" : "BASE_UNIT_OR_EACH",
"gtin" : "08711728556206",
"services" : [
{
"label" : "etiket controle",
"collection" : "gtins"
}
]
}
]
}
to
{
"_id" : "764",
"meta" : {
"groupsId" : "764",
"type" : "DRYGR"
},
"units" : [
{
"unit" : "BASE_UNIT_OR_EACH",
"gtin" : "08711728556206",
"services" : [
{
"label" : "AuditLabel",
"collection" : "gtins"
}
]
}
]
}
Try this code its work's for me
db.getCollection('assortiment').updateMany(
{
"units.services.label": "etiket controle"
},
{
"$set":
{ "units.$[].services.$[].label": "AuditLabel" }
}
)

update particular single subdocument in nested array in nodejs mongodb

I am new to nodejs and mongo db. I have nested subdocument type schema in mongo. Document type is Process => Subprocess => tasks => configs. These are in the format of nested arrays and can be multiple.
{
"_id" : ObjectId("5bcec0ee711fe511f4848c1d"),
"process_title" : "customer acquisition",
"subprocess" : [
{
"_id" : ObjectId("5bcec0f8711fe511f4848c1e"),
"subprocess_title" : "application",
"tasks" : [
{
"_id" : ObjectId("5bcec158711fe511f4848c1f"),
"task_title" : "pre screening",
"task_slug" : "pre-screening",
"task_configs" : [
{
"_id" : ObjectId("5bcec4b912582b01b84fe47a"),
"next_task" : "thanks"
}
]
},
{
"_id" : ObjectId("5bcec190711fe511f4848c20"),
"task_title" : "thanks",
"task_slug" : "thanks",
"task_configs" : [
{
"_id" : ObjectId("5bcec469ab23ab1fc0bbb9ed"),
"form_field" : "responseMessage",
"expression" : "=",
"expression_value" : "Approved4",
"success_task" : "signup",
"success_sub_process_id" : "5bcec0f8711fe511f4848c1e",
"fail_task" : "thanks",
"fail_sub_process_id" : "5bcec0f8711fe511f4848c1e"
}
]
},
{
"_id" : ObjectId("5bcec1c3711fe511f4848c21"),
"task_title" : "signup",
"task_slug" : "signup",
"task_configs" : [
{
"_id" : ObjectId("5bcec469ab23ab1fc0bbb9ed"),
"form_field" : "responseMessage",
"expression" : "=",
"expression_value" : "Approved4",
"success_task" : "signup",
"success_sub_process_id" : "5bcec0f8711fe511f4848c1e",
"fail_task" : "thanks",
"fail_sub_process_id" : "5bcec0f8711fe511f4848c1e"
}
]
}
]
}
],
"created_at" : ISODate("2018-10-23T06:34:22.676Z"),
"updated" : ISODate("2018-10-23T06:34:22.676Z"),
"__v" : 0
}
Now I want to update task_configs for a particular task. I am updating task_config on the basis of task_slug.
I found a way myself to update above query.
Workflow.updateOne({ "_id": new ObjectId(req.body.process_id), "subprocess._id": new ObjectId(req.body.sub_process_id), "subprocess.tasks.task_slug": req.body.task_slug },
{
$set: {
'subprocess.$.tasks.$[j].task_configs': req.body.task_configs
}
},
{
arrayFilters: [
{
"j.task_configs": req.body.task_configs
}]
})
.then(function (resp) {
console.log(resp)
res.json({ status: 'success', resp });
}).catch(function (err) {
res.status(500).json(err);
})

Mongo pull object from array inside array

i have inside my mongoDB collection this document
{
"_id" : ObjectId("5b633025579fac22e74bf3be"),
"FLAGS" : [
{
"toSent" : [
{
"_id" : ObjectId("5b633025579fac22e74bf3c2"),
"phone" : "+84404040404"
},
{
"_id" : ObjectId("5b633025579fac22e74bf3c1"),
"phone" : "+212652253403"
},
{
"_id" : ObjectId("5b633025579fac22e74bf3c0"),
"phone" : "+212123456788"
}
],
"_id" : ObjectId("5b633025579fac22e74bf3bf"),
"action" : "group_p_a"
},
{
"toSent" : [
{
"_id" : ObjectId("5b633031579fac22e74bf3c9"),
"phone" : "+212651077199"
},
{
"_id" : ObjectId("5b633031579fac22e74bf3c8"),
"phone" : "+84404040404"
},
{
"_id" : ObjectId("5b633031579fac22e74bf3c7"),
"phone" : "+212652253403"
},
{
"_id" : ObjectId("5b633031579fac22e74bf3c6"),
"phone" : "+212123456788"
}
],
"_id" : ObjectId("5b633031579fac22e74bf3c5"),
"action" : "group_p_a"
}
],
"time" : ISODate("2018-08-02T16:24:05.747+0000"),
"action_user_phone" : "+212123456788",
"idGroup" : "e534379a-1580-4568-b5ec-6eaf981538d2",
"nomGroup" : "MOH FOR EVER",
"__v" : NumberInt(0)
}
TODO
I need to remove for example this element { "_id" : ObjectId("5b633025579fac22e74bf3c2"), "phone" : "+84404040404"}
WHAT I DID
GroupEvents.update({}, {$pull:{FLAGS:{$elemMatch:{toSent:{phone: "+84404040404"} }}}},function(err,ret){
if(err)
console.log("error"+err);
if(ret)
console.log(ret);
});
It remove all what's inside toSent event if it doesn't match.
Any help please
You need to use $ positional operator instead of $elemMatch here
GroupEvents.update(
{ "Flags.toSent.phone": "+84404040404" },
{ "$pull": { "FLAGS.$.toSent": { "phone": "+84404040404" }}},
)
If you want remove from every element of FLAGS array this you need to use $[] the all positional operator
GroupEvents.update(
{ "Flags.toSent.phone": "+84404040404" },
{ "$pull": { "FLAGS.$[].toSent": { "phone": "+84404040404" }}},
)

Remove of $unwind operation from array in mongodb

There are multiple collections one of these are.
users
place
The document stored in the database which is given below.
{
"_id" : "1eca51f0-538d-11e8-89fc-d125355b590d",
"organization" : [
{
"associationIds" : {
"dObjectIds" : [
{
"dObjectData" : {
"objectId" : "fd047ddf-61c2-4df2-8241-62af0399c8c1",
"objectName" : "shift",
"dObjectId" : "49492544-e4e3-491b-b967-a6f62330da3f"
}
}
]
},
"organizationId" : "1c3f6150-538d-11e8-89fc-d125355b590d",
"privelege" : "Admin",
"organizationName" : "ABC"
},
{
"associationIds" : {
"dObjectIds" : [
{
"dObjectData" : {
"objectId" : "ad047ddf-61c2-4df2-8241-62af0399c5c1",
"objectName" : "shift",
"dObjectId" : "38492544-e4e3-491b-b967-a6f62330da3f"
}
},
{
"dObjectData" : {
"objectId" : "fd047ddf-61c2-4df2-8241-62af0399c8c2",
"objectName" : "department",
"dObjectId" : "49492544-e4e3-491b-b967-a6f62330da1f"
}
}
]
},
"organizationId" : "1c3f6150-538d-11e8-89fc-d125355b591d",
"privelege" : "Manager",
"organizationName" : "XYZ"
}
]}
I'm using these query.
db.users.aggregate([
{$match: {'_id': '1eca51f0-538d-11e8-89fc-d125355b590d'}},
{$unwind :'$organization'},
{$match:{'organization.organizationId':'1c3f6150-538d-11e8-89fc-d125355b591d'}},
{$unwind:'$organization.associationIds.dObjectIds'},
{'$lookup': {
'from': 'places',
localField:'organization.associationIds.dObjectIds.dObjectData.dObjectId',
foreignField: 'dObjectData.dObjectId',
as: 'associationData'
}
},
{'$project': {
'associationData': 1
}
}
])
I have used $unwind two times in a query which has more expensive.Is there any way or operation which can we use instead of multiple times of $unwind.
NOTE: I waana result like this(result of associationData which get the velue from other collection so I used $lookup)
{
_id" : "c6114ee0-c82f-11e6-9b1e-6140212f8693",
"associationData" : [
{
"_id" : "f09f5d70-ad7e-11e7-87bd-cd873956707e",
"dObjectData" : {
"departmentName" : "CEO & Directors",
"dObjectId" : "ab034106-ad7d-11e7-abc4-cec278b6b50a",
"objectName" : "Departments",
"objectId" : "63735ee2-ad79-11e7-abc4-cec278b6b50a",
"updatedOn" : ISODate("2017-10-10T11:20:37.255+05:30"),
"addedOn" : ISODate("2017-10-10T11:20:37.255+05:30")
},
"associationIds" : {
"organizationId" : "af39bc69-1938-4149-b9f7-f101fd9baf73",
"placeIds" : [ ],
"assignmentIds" : [ ],
"beaconIds" : [ ],
"userIds" : [ ]
}
}]}
I'll be very thankful.

Targeting a query in Mongo to find and email nested in an object

I'm trying to do a query for an endpoint in my Node/Express & Mongo/Mongoose API.
Here is a representation of the document/schema I'm trying to query:
{
"_id" : ObjectId("59474bc3478604a75e1980e2"),
"initial" : "D",
"last_name" : "Spitz",
"first_name" : "Chris",
"owner_id" : "59474b92478604a75e1980e1",
"contacts" : [
{
"last_name" : "Jones",
"first_name" : "Tom",
"_id" : ObjectId("5947fd928389ffb393fbc310"),
"addresses" : [ ],
"phones" : [ ],
"emails" : [
{
"email_type" : "home",
"email_address" : "runner#running.com",
"_id" : ObjectId("5947fd928389ffb393fbc311")
},
{
"email_type" : "home",
"email_address" : "jake#samsonite.com",
"_id" : ObjectId("5947ff9ed8fa7cb4c781acc9")
}
]
},
{
"last_name" : "Smith",
"first_name" : "Linda",
"_id" : ObjectId("5947ff9ed8fa7cb4c781acc8"),
"addresses" : [ ],
"phones" : [ ],
"emails" : [
{
"email_type" : "home",
"email_address" : "chris#chrisnakea.com",
"_id" : ObjectId("5947ff9ed8fa7cb4c781acc9")
}
]
}
]
}
I'm trying to check if an email exists in the "contacts.email" array of the document.
Here is the way I'm checking (based on the whey it the item is nested in the schema above):
Profile.find({'contacts.emails.email_address':req.body.invited_email}, function(err, profile){
if(err)
console.log('Error in looking for profile.');
if(profile.contacts.emails.email_address !== null){
console.log('Found contact: ' + profile.contacts.emails.email_address);
} else {
console.log('Contact does not exist');
}
})
But for some reason I'm getting a "TypeError: Cannot read property 'emails' of undefined" error in the console when testing.
What am I missing here?

Resources