Mongoose find anywhere inside document - node.js

i need to find record matching userId. the userId can be in any level of document.
It can be in parent level or it can be inside friends array.
[{
"_id": "543357620c9af6066e689713",
"createdDate": "2014-10-06 08:00 pm",
"cancle": false,
"eventDate": "2014/12/12",
"eventstatus": true,
"location": "chennai",
"userId": "54334def7e85de48638d1069",
"createdBy": "four",
"eventName": "jamba",
"__v": 0,
"friends": []
},
{
"_id": "543356fe0c9af6066e68970c",
"createdDate": "2014-10-06 07:59 pm",
"cancle": false,
"eventDate": "2014/12/12",
"eventstatus": true,
"location": "chennai",
"userId": "54310801e2659ecc3650100b",
"createdBy": "one",
"eventName": "tea ",
"__v": 0,
"friends": [
{
"userId": "54310814e2659ecc3650100c",
"userName": "two",
"phoneNumber": "22222222"
},
{
"userId": "54310945e2659ecc3650100d",
"userName": "three",
"phoneNumber": "33333333"
},
{
"userId": "54334def7e85de48638d1069",
"userName": "four",
"phoneNumber": "44444444"
}
]
}]
i am trying for long time. Any help is highly appreciated.

You need the $or operator. Also, you don't need to iterate to query for elements within an array. Assuming your collection is named Events:
Events.find({
$or: [
{ _id: req.params.userId },
{ 'friends.userId': req.params.userId }
]
}).exec();

Related

$lookup and $group on Mongodb Aggregation

So i have an document of answers from user with structure like this:
[{
"_id": {
"$oid": "636e685d1e1b4aa82f7e87c7"
},
"userId": {
"$oid": "6369b17b11e02557349d8e37"
},
"formId": {
"$oid": "6361d3bf914c7e5a21efa190"
},
"title": "Order Kerja Produksi (KSNI)",
"username": "22000510",
"date": "2022-11-11",
"createdAt": 1668180061,
"updatedAt": 1668180061,
"__v": 0,
"position": "Foreman",
"department": "Production"
},
{
"_id": {
"$oid": "636e699c1e1b4aa82f7e87cb"
},
"userId": {
"$oid": "6369b17b11e02557349d8e37"
},
"formId": {
"$oid": "6361d3bf914c7e5a21efa190"
},
"title": "Order Kerja Produksi (KSNI)",
"username": "22000510",
"date": "2022-11-11",
"createdAt": 1668180380,
"updatedAt": 1668180380,
"__v": 0,
"department": "Production",
"position": "Foreman"
},
{
"_id": {
"$oid": "636e6ace1e1b4aa82f7e87cf"
},
"userId": {
"$oid": "6369b17b11e02557349d8e37"
},
"formId": {
"$oid": "6361d3bf914c7e5a21efa190"
},
"title": "Order Kerja Produksi (KSNI)",
"username": "22000510",
"date": "2022-11-11",
"createdAt": 1668180686,
"updatedAt": 1668180686,
"__v": 0,
"department": "Production",
"position": "Foreman"
}
]
each NIK has assigned with SPV on the Users document, that have structure like this:
{
"_id": {
"$oid": "6369b17b11e02557349d8de6"
},
"password": "$2b$10$whBbgZRMsIMCgKy/EJAwXefSdZNnrK5b.cSOYXTqu7g5a2uwCddKm",
"NIK": "19000298",
"department": "Production",
"__v": 0,
"createdAt": 1667871099,
"updatedAt": 1667871099,
"plant": "RANC",
"Gedung_Zona": "No Status",
"SPV": "JAMJAM J",
"Sector": "2"
},
{
"_id": {
"$oid": "6369b17b11e02557349d8de7"
},
"password": "$2b$10$whBbgZRMsIMCgKy/EJAwXefSdZNnrK5b.cSOYXTqu7g5a2uwCddKm",
"NIK": "20000100",
"Group_Shift": "R1",
"role": "user",
"__v": 0,
"createdAt": 1667871099,
"updatedAt": 1670974129,
"plant": "RANC",
"Gedung_Zona": "No Status",
"SPV": "JAMJAM J",
"Sector": "3"
},
]
I want to aggregate the answers from answers document with condition from users document where condition like this:
{$match:{SPV:"SPV_name"}}
Is that a possible way to produce it into this kind of response with condition above using $lookup and $group?
If thats possible any help on how to produce that?
any help will be very thankful
Here is what i want the response from the query..
{
_id:1243135421412,
formId:123123123123,
title:"title of the question",
username:22004627,
date:2022-10-10,
createdAt:1234125525,
SPV:"SPV_NAME",
},
{
_id:1243135421412,
formId:123123123123,
title:"title of the question",
username:22004777,
date:2022-10-12,
createdAt:1234125525,
SPV:"SPV_NAME",
}
here is my try but it keeps returning error :
MongoServerError: Expression $arrayElemAt takes exactly 2 arguments. 1 were passed in.
Here is my try:
db.answers.aggregate([{$lookup:{from:"users",pipeline:[{$match:{SPV:"JAMJAM JAMALUDIN"}}],as:"data"}}])

mongoose find multiple fileds then add array of object

I have the following mongoose collection
{
"_id": "5f494ca2d84e5d2ae800d5a4",
"email": "test#gmail.com",
"customer": [
{
"entries": [],
"payment": [],
"_id": "5f4950e7f4e0162c2c8af05f",
"name": "demo",
"mobile": 8877887788
},
{
"entries": [],
"payment": [],
"_id": "5f49514230dc8e3f0063f5e1",
"name": "demo2",
"mobile": 8877887788
},
{
"entries": [],
"payment": [],
"_id": "5f4956d92d83c03e68905fbb",
"name": "demo3",
"mobile": 8877887788
}
],
"createdAt": "2020-08-28T18:27:46.090Z",
"updatedAt": "2020-08-28T19:27:25.882Z",
"__v": 5
}
We have multiple users Above this is only 1 user schema
User have multiple Customers
Goal :-
Verify User -> Select particular Customer -> push entries Values in particular Customer
Find user by Email ID
then We have multiple Customers in this User so I want to find particular 1 Customer and target entries array .. and push value in entries Array
eg:- What i Want
{
"_id": "5f494ca2d84e5d2ae800d5a4",
"email": "test#gmail.com",
"customer": [
{
"entries": [
{ "amount" : 40 ,
"date" : "2020-08-28T19:27:25.882Z"
}
],
"payment": [],
"_id": "5f4950e7f4e0162c2c8af05f",
"name": "demo",
"mobile": 8877887788
},
{
"entries": [],
"payment": [],
"_id": "5f49514230dc8e3f0063f5e1",
"name": "demo2",
"mobile": 8877887788
},
{
"entries": [],
"payment": [],
"_id": "5f4956d92d83c03e68905fbb",
"name": "demo3",
"mobile": 8877887788
}
],
"createdAt": "2020-08-28T18:27:46.090Z",
"updatedAt": "2020-08-28T19:27:25.882Z",
"__v": 5
}
So I would use mongoose find by id to find the user then for each through the customer array, then save your changes.
db.<collectionName>.findById(id).then((collection) => {
collection.customer.forEach((customer, index) => {
if (customer._id === custId) {
collection.customer[index] = { ...collection.customer[index], quantity: newQuantity }
};
});
db.<collectionName>.findByIdAndUpdate(id, collection);
});
Something like that.

How to filter results from collection the $lookup in mongoose

i want to filter the result as the following in mongodb. I use $lookup to populate the result from another collection. Please check my following code
This code below is what i get
{
"_id": "5f3d563122de0730d0f6a754",
"barcode": "1234",
"productname": "Lays Packet",
"brandName": "Lays",
"productSize": "12",
"price": "12",
"quant": "12",
"imageurl": "http://localhost:3000/images/imageurl-1597855281050.jpg",
"remaining": "12",
"creator": "3d943b957fb5db510d824c5cbd6e8f7d",
"__v": 0,
"source": [
{
"_id": "5f3a9bbc325a074240a1a815",
"firstname": "test",
"lastname": "test",
"storename": "test",
"gst": "test",
"phoneNumber": 1,
"email": "1#demo.com",
"address1": "test",
"address2": "test",
"city": "test",
"state": "test",
"country": "test",
"zip": "1",
"password": "1",
"usertype": 3,
"unique_SHOP": "3d943b957fb5db510d824c5cbd6e8f7d",
"__v": 0
}
]
},
How to retrieve only unique_SHOP and zip from source listing.I want result like the one below with one or more fields
{
"_id": "5f3d563122de0730d0f6a754",
"barcode": "1234",
"productname": "Lays Packet",
"brandName": "Lays",
"productSize": "12",
"price": "12",
"quant": "12",
"imageurl": "http://localhost:3000/images/imageurl-1597855281050.jpg",
"remaining": "12",
"creator": "3d943b957fb5db510d824c5cbd6e8f7d",
"__v": 0,
"source": [
{
"zip": "1",
"unique_SHOP": "3d943b957fb5db510d824c5cbd6e8f7d",
}
]
},
The query i use
List.aggregate([
{$match:
{ productname: { $regex: req.params.query,$options: "i" }}
},
{ $lookup:{
from: "suppliers",
localField: "creator",
foreignField: "unique_SHOP",
as: "source"
}
},
])
You can try $lookup with pipeline,
$match condition of creator id
$project to display required fields
{
$lookup: {
from: "suppliers",
as: "source",
let: { creator: "$creator" },
pipeline: [
{
$match: {
$expr: { $eq: ["$$creator", "$_id"] }
}
},
{
$project: {
_id: 0,
zip: 1,
unique_SHOP: 1
}
}
]
}
}
Playground

Flter mongodb database using mongoose nodejs

I need to filter some users according to some fixed criteria. I have a user collection and a talent collection. The talent collection holds the reference to a master category collection.
What I need is to filter these users according to the category in the talent collection and some keys from the user collection.
For example I need to search for a user whose gender is 'male' and education 'BTech' and will have talents as a programmer and tester
my user collection is like,
{
"_id": "5f1939239bd35429ac9cd78f",
"isOtpVerified": "false",
"role": "user",
"adminApproved": 1,
"status": 0,
"languages": "Malayalam, Tamil, Telugu, Kannada",
"name": "Test user",
"email": "test#email.com",
"phone": "1234567890",
"otp": "480623",
"uid": 100015,
"bio": "Short description from user",
"dob": "1951-09-07T00:00:00.000Z",
"gender": "Male",
"education": "Btech",
"bodyType": "",
"complexion": "",
"height": "",
"weight": "",
"requests": [],
"location": {
"place": "place",
"state": "state",
"country": "country"
},
"image": {
"avatar": "5f1939239bd35429ac9cd78f_avatar.jpeg",
"fullsize": "5f1939239bd35429ac9cd78f_fullsize.png",
"head_shot": "5f1939239bd35429ac9cd78f_head_shot.jpeg",
"left_profile": "5f1939239bd35429ac9cd78f_left_profile.png",
"right_profile": "5f1939239bd35429ac9cd78f_right_profile.png"
},
"__v": 42,
"createdAt": "2020-07-23T07:15:47.387Z",
"updatedAt": "2020-08-18T18:54:22.272Z",
}
Talent collection
[
{
"_id": "5f38efef179aca47a0089667",
"userId": "5f1939239bd35429ac9cd78f",
"level": "5",
"chars": {
"type": "Fresher",
},
"category": "5f19357b50bcf9158c6be572",
"media": [],
"createdAt": "2020-08-16T08:35:59.692Z",
"updatedAt": "2020-08-16T08:35:59.692Z",
"__v": 0
},
{
"_id": "5f3b7e6f7e322948ace30a2c",
"userId": "5f1939239bd35429ac9cd78f",
"level": "3",
"chars": {
"type": "Fresher",
},
"category": "5f19359250bcf9158c6be573",
"media": [
{
"adminApproved": 0,
"status": 0,
"_id": "5f3c22573065f84a48e04a14",
"file": "id=5f1939239bd35429ac9cd78f&dir=test&img=5f1939239bd35429ac9cd78f_image_undefined.jpeg",
"description": "test",
"fileType": "image",
"caption": "test file"
},
{
"adminApproved": 0,
"status": 0,
"_id": "5f3c2d7a8c7f8336b0bfced2",
"file": "id=5f1939239bd35429ac9cd78f&dir=test&img=5f1939239bd35429ac9cd78f_image_1.jpeg",
"description": "this is a demo poster for testing",
"fileType": "image",
"caption": "A Test Poster"
}
],
"createdAt": "2020-08-18T07:08:31.532Z",
"updatedAt": "2020-08-18T19:35:22.899Z",
"__v": 2
}
]
And the category in the above document is a separate one populated to this. the category collection as,
[
{
"_id": "5f19359250bcf9158c6be573",
"status": true,
"title": "Testing",
"description": "Application tester",
"code": "test",
"characteristics": [],
"createdAt": "2020-07-23T07:00:34.221Z",
"updatedAt": "2020-07-23T07:00:34.221Z",
"__v": 0
},
{
"status": true,
"_id": "5f29829a705b4e648c28bc88",
"title": "Designer",
"description": "UI UX Designer",
"code": "uiux",
"createdAt": "2020-08-04T15:45:30.125Z",
"updatedAt": "2020-08-04T15:45:30.125Z",
"__v": 0
},
{
"_id": "5f19357b50bcf9158c6be572",
"status": true,
"title": "programming",
"description": "Java programmer",
"code": "program",
"createdAt": "2020-07-23T07:00:11.137Z",
"updatedAt": "2020-07-23T07:00:11.137Z",
"__v": 0
}
]
So my filter terms will be;
{
categories: ["5f19359250bcf9158c6be573", "5f19357b50bcf9158c6be572"],
minAge: 18,
maxAge: 25,
minHeight: 5,
maxHeight: 6,
minWeight: 50,
maxWeight: 80,
complexion: "white",
gender: "male",
}
And the expected result will be a user have both the above talents and followed conditions,
{
users: { ..User details.. },
medias: { ...medias from the matching talents.. }
}
If there are two collections you need to join them either by primary key or _id with foriegn fields and you can use $lookup with $match to filter down.
Documentation
You need to use $lookup with pipeline,
$match you condition for category match
$lookup to join users collection
$match conditions for users collections fields
$match exclude documents that don't found matching users of criteria passed in conditions
db.talents.aggregate([
{
$match: {
category: { $in: ["5f19359250bcf9158c6be573", "5f19357b50bcf9158c6be572"] }
}
},
{
$lookup: {
from: "users",
as: "users",
let: { userId: "$userId" },
pipeline: [
{
$match: {
$expr: {
$and: [
{ $eq: ["$$userId", "$_id"] },
{ $eq: ["$gender", "Male"] },
{ $eq: ["$education", "Btech"] }
// ... add you other match criteria here
]
}
}
}
]
}
},
{ $match: { users: { $ne: [] } } }
])
Playground

Query to retrieve every subdocument alone without passing parent id using Mongoose

Here i like to explain my problem.
How can i write a mongoose query to retrieve every subdocument from JSON without passing parent_id.
[
{
"_id": "56a320003fe17cc7363dd0d7",
"name": "Leanna Jacobson",
"gender": "female",
"friends": [
{
"id": 0,
"name": "Riley Case"
},
{
"id": 1,
"name": "Herman Carter"
},
{
"id": 2,
"name": "Pacheco Woodard"
}
]
},
{
"_id": "56a3200001501cfa1ea2641d",
"name": "Juliana Bonner",
"gender": "female",
"friends": [
{
"id": 0,
"name": "Keller Woodward"
},
{
"id": 1,
"name": "Fern Knight"
},
{
"id": 2,
"name": "Cain Richards"
}
]
},
{
"_id": "56a3200006864c78ecb1aeed",
"name": "Gena Stark",
"gender": "female",
"friends": [
{
"id": 0,
"name": "Kate Franco"
},
{
"id": 1,
"name": "Araceli Mcclure"
},
{
"id": 2,
"name": "Molly Nelson"
}
]
},
{
"_id": "56a320006d868155161038b6",
"name": "Eve Gonzalez",
"gender": "female",
"friends": [
{
"id": 0,
"name": "Pam Lang"
},
{
"id": 1,
"name": "Christy Marks"
},
{
"id": 2,
"name": "Donovan Warren"
}
]
},
{
"_id": "56a3200066b94852f5680568",
"name": "Coleman Wooten",
"gender": "male",
"friends": [
{
"id": 0,
"name": "Roberta Olson"
},
{
"id": 1,
"name": "Roseann Reid"
},
{
"id": 2,
"name": "Kerri Russell"
}
]
}
]
Here i need to retrieve every friends details from the subdocument array friends for every parent.
so how can i write query for this?????
Suppose the name of your schema is Person, try this one.
//find all document, only select `friends` field from every document
Person.find({}, 'friends', function (err, friends) {
// the return friends is the [[friends], [friends], ...]
});

Resources