Retrieve object information within an array with mongoose - node.js

I'm making an API Rest with node, express, typescript and mongoose. I have a method GET that return this result:
{
"success": true,
"status": 200,
"message": "categories listed",
"data": [
{
"_id": "612650e55fe1ce0de138e2af",
"products": [
{
"_id": "612650e55fe1ce0de138e2b0",
"productID": {
"reviews": [
"611e61ba8cb43f7454787ebb",
"611e62008cb43f7454787ebc"
],
"_id": "610b18f3e2244a187b36f2d7",
"title": "PS4",
"description": "La mejor consola del mercado del mundo, mundial",
"photo": "https://amazon-clone-jparrot.s3.amazonaws.com/1628123519052",
"price": 400,
"stockQuantity": 23,
"__v": 0,
"category": "60fc6454b68717acc239cc6a",
"owner": "610b9ed8763da4308223aae0",
"averageRating": null,
"id": "610b18f3e2244a187b36f2d7"
},
"quantity": 1,
"price": 400
}
],
"owner": {
"_id": "611d2d39dfcc705972c1ccb8",
"name": "Jaume",
"email": "jaumeparrot2#gmail.com",
"password": "$2a$10$Rv9Rzrff6578feCdDjyeKuarKCSHYRqKp5n5wTi2IWtcLBOupvPgu",
"__v": 0,
"address": "611e9ccdf47c7a7a9cb1d5d9"
},
"estimatedDelivery": "Wednesday September 1st",
"__v": 0
}
]
}
The problem is that I need to retrieve the object "owner", that is, I need to recover this json:
{
"success": true,
"status": 200,
"message": "categories listed",
"data": [
{
"_id": "612650e55fe1ce0de138e2af",
"products": [
{
"_id": "612650e55fe1ce0de138e2b0",
"productID": {
"reviews": [
"611e61ba8cb43f7454787ebb",
"611e62008cb43f7454787ebc"
],
"_id": "610b18f3e2244a187b36f2d7",
"title": "PS4",
"description": "La mejor consola del mercado del mundo, mundial",
"photo": "https://amazon-clone-jparrot.s3.amazonaws.com/1628123519052",
"price": 400,
"stockQuantity": 23,
"__v": 0,
"category": "60fc6454b68717acc239cc6a",
"owner": {
"_id": "611d2d39dfcc705972c1ccb8",
"name": "Jaume",
"about": "My na is Jaume",
"__v": 0
},
"averageRating": null,
"id": "610b18f3e2244a187b36f2d7"
},
"quantity": 1,
"price": 400
}
],
"owner": {
"_id": "611d2d39dfcc705972c1ccb8",
"name": "Jaume",
"email": "jaumeparrot2#gmail.com",
"password": "$2a$10$Rv9Rzrff6578feCdDjyeKuarKCSHYRqKp5n5wTi2IWtcLBOupvPgu",
"__v": 0,
"address": "611e9ccdf47c7a7a9cb1d5d9"
},
"estimatedDelivery": "Wednesday September 1st",
"__v": 0
}
]
}
For generate this JSON, I'm using this method:
https://github.com/jparrot92/amazon-clone-back/blob/master/src/controllers/order.ts

To retrieve you should use data.owner. This will give owner details as object.

This is the solution:
const products = await Order.find({ owner: req.user._id })
.populate('owner')
.populate({
path: 'products.productID',
populate: {
path: 'owner',
model: 'Owner',
},
})
.exec();

Related

How to findOneAndUpdate MongoDB object inside array from multiple arrays inside object

I am new to mongodD. Although i have wrote correct logic to push object inside cardsData bankCardsArray, but i am not able to make logic to edit a card.
**I have following Data in MongoDB, **
UserData = {
"_id": "63b43ab32fc8d3c100cafecc",
"name": "Praveen Lohar",
"email": "pr********#gmail.com",
"password": "$2b$12$3nwifHakrBu94BwLXAC4Nu16Kw0.xyW8vAIPTMSgY7cYttVklDIZq",
"loginIdsArray": [
{
"title": "Airtel App",
"logoIndex": 3,
"category": "Finance",
"app": "Airtel Thanks",
"username": "p******#gmail.com ",
"password": "xxxxxxx",
"isFavourite": false,
"_id":"63b440ee738a50fc333df3ca"
}
],
"cardsData": {
"bankCardsArray": [
{
"title": "SBI CC",
"logoIndex": 72,
"category": "Bank",
"cardHolder": "Prsscscs",
"cardNumber": "524xxxxxxxx20xx",
"expiry": "23/54",
"cvv": "00",
"isFavourite": false,
"_id": "63b974adb9acaa24a4ebec8b"
},
{
"title": "AXIS CC",
"logoIndex": 85,
"category": "Bank",
"cardHolder": "blsllslss",
"cardNumber": "524xxxxxxxx20xx",
"expiry": "23/54",
"cvv": "00",
"isFavourite": false,
"_id": "63b974adb9acaa24a4ebe5f"
}
],
"identityCardsArray": [
{
"title": "Aadhar Card",
"logoIndex": 98,
"category": "Identity",
"cardHolder": "Name_1",
"cardNumber": "54*******455454",
"issueDate": "2012",
"dob": "23/05",
"isFavourite": false,
"_id":"63b974e6bd0d03c116955f67"
}
],
"licenseCardsArray": [
{
"title": "Two Wheeler License",
"logoIndex": 0,
"category": "License",
"cardHolder": "Klaus Michealson",
"licenseNumber": "RJ/22/ADL-542/474/01",
"expiry": "2036",
"dob": "13/06",
"isFavourite": false,
"_id":"63b97535bd0d03c116955f69"
}
]
}
}
I want to find the user with _id
Then for that user i want to got to cardsData object
Then in cardsData object i want to got to bankCardsArray
Then in bankCardsArray , i want to update fields of a card with particular id
Const res = findOneAndUpdate(
{ 'cardsData.bankCardsArray._id':card_id },
{ $set{ 'cardsData.bankCardsArray.$.title': req.body.title });
Use "." operator to access nested fields.
Refer these mongodb documentation
query-array-of-documents
query-embedded-documents.
Hope this helps.

Remove nested categories in mongo

I want when a category is deleted. All its child categories and its own categories will be deleted.
For example, I want if the web development category is deleted. All its child categories (delete Django and Django Channel)
{
"statusCode": 200,
"data": {
"categories": [
{
"_id": "62fdfb567bb46dcf93b3717f",
"title": "Web development",
"parent": null,
"position": "important",
"slug": "-eb-development",
"createdAt": "2022-08-18T08:41:58.826Z",
"updatedAt": "2022-08-18T08:41:58.826Z",
"children": [
{
"_id": "62fdfb677bb46dcf93b3718d",
"title": "Django",
"parent": "62fdfb567bb46dcf93b3717f",
"position": "unimportant",
"slug": "-jango",
"createdAt": "2022-08-18T08:42:15.557Z",
"updatedAt": "2022-08-18T08:42:15.557Z",
"children": [
{
"_id": "62fdfb857bb46dcf93b371a1",
"title": "Django chennels",
"parent": "62fdfb677bb46dcf93b3718d",
"position": "unimportant",
"slug": "-jango-chennels",
"createdAt": "2022-08-18T08:42:45.665Z",
"updatedAt": "2022-08-18T08:42:45.665Z",
"children": [],
"id": "62fdfb857bb46dcf93b371a1"
}
],
"id": "62fdfb677bb46dcf93b3718d"
}
],
"id": "62fdfb567bb46dcf93b3717f"
}
]
}
}
I wrote a code for this which does not work properly and removes only one child from the desired category.
const category = await this.checkExistCategory(id);
const deleteResult = await Category.deleteMany({
$or: [{ _id: category._id }, { parent: category._id }],
});
Thank you very much for helping me!!

How to filter the response from mongoDB, so nested arrays will include only items that meet a condition?

My documents look like this
{
"_id": {
"$oid": "62825f71005ce00c5f0235c1"
},
"user": "jon",
"roles": {
"User": 2001,
},
"STOCK ": [
{
"sku": "BLACK-M",
"productname": "BLACK",
"sendout": 0,
"recived": 1,
"totalinstock": 40,
"location": "B32",
"_id": {
"$oid": "62826016005ce00c5f0235c8"
}
},
{
"sku": "CJNS",
"productname": "89796363",
"sendout": 0,
"recived": 45,
"totalinstock": 0,
"location": "B232",
"_id": {
"$oid": "62836f2d56b4f1ac79c99b8d"
}
}
],
"ORDERS": [
{
"date": {
"$date": "2022-06-02T15:23:58Z"
},
"OrderNumber": "745607",
"City": "xxxxx",
"Address": "yyyyyy",
"Phone": "8678678678",
"Name": "Holly ",
"Trackingnumber": 40,
"ZipCode": 00000,
"Province": "New ",
"Quantity": [
1
],
"Product_Name": [
" pants pants"
],
"SKU": [
"CJNS"
],
"_id": {
"$oid": "6298d61ba6eeec72b78332a7"
}
},
{
"date": {
"$date": "2022-06-02T15:23:58Z"
},
"OrderNumber": "748840",
"City": "xxxxx",
"Address": "yyyyyy",
"Phone": "354353454",
"Name": "Michael",
"Trackingnumber": 0,
"ZipCode": 00000,
"Province": "North",
"Quantity": [
1
],
"Product_Name": [
" pants pants"
],
"SKU": [
"CJNS"
],
"_id": {
"$oid": "6298d61ba6eeec72b78332a9"
}
}
]
}
I successful to return all the objects in STOCK or all the objects in ORDERS
Through this query
const foundUser= await User.find({"user":req.body.user},("Orders") ).exec()
Now I want to filter the response to include only items where "Trackingnumber" is different from 0
For the sample data I expect to receive only
{
"date": {
"$date": "2022-06-02T15:23:58Z"
},
"OrderNumber": "748840",
"City": "xxxxx",
"Address": "yyyyyy",
"Phone": "354353454",
"Name": "Michael",
"Trackingnumber": 0,
"ZipCode": 00000,
"Province": "North",
"Quantity": [
1
],
"Product_Name": [
" pants pants"
],
"SKU": [
"CJNS"
],
"_id": {
"$oid": "6298d61ba6eeec72b78332a9"
}
}
You can use an aggregation pipeline with a $filter for this:
db.collection.aggregate([
{
$match: {
"user": "jon"
}
},
{
$project: {
ORDERS: {
$filter: {
input: "$ORDERS",
as: "item",
cond: {$ne: ["$$item.Trackingnumber", 0]}
}
}
}
}
])
Playground example
User.find({"Orders" : {"Trackingnumber": 0} })

Edit (Update) Specific value in MongoDB Document

I Want to update Only the value of payStatus
data : {
"profile": {
"guestName": "Hussein Khalil",
"mobile": "01223550119",
"email": "husseinkhalil33#gmail.com"
},
"hotelRoomingList": {
"child": {
"childAges": [
2,
4
],
"childNo": 2
},
"hotelStatus": "Not Confirmed",
"roomsNo": 3,
"adultsNo": 2,
"travelAgent": "Nilsen",
"hotelConfNo": "G1B412",
"roomingNotes": "Some rooming Notes",
"roomingList": {
"_id": "604b79ecb102efdea80a0698",
"roomingName": "Pyramids",
"roomingDescription": "this is Pyramids travels",
"revenueMonth": "jul",
"startedDate": "2021-03-12T14:25:48.830Z",
"__v": 0,
"id": "604b79ecb102efdea80a0698"
},
"hotel": {
"_id": "604d511964927d1759884e36",
"hotelName": "Concorde Front",
"__v": 0,
"id": "604d511964927d1759884e36"
},
"roomType": {
"_id": "604d516564927d1759884e37",
"roomType": "double",
"__v": 0,
"id": "604d516564927d1759884e37"
},
"mealPlane": {
"_id": "604aa5a7246f847df848c796",
"mealPlane": "SAL",
"__v": 0,
"id": "604aa5a7246f847df848c796"
},
"nights": 8,
"arrivalDate": "2021-03-27T22:00:00.000Z",
"departureDate": "2021-04-04T22:00:00.000Z"
},
"customerAccount": {
"payStatus": "not-gura-not-sure",
"fullPay": 3000,
"hotelCost": 2050,
"transportCost": 150,
"otherCost": 50,
"paid": 1250,
"optionDate": "2021-04-05T22:00:00.000Z",
"customerNotes": "some customerNotes",
"restOfPay": 1750,
"profit": 750
},
"transportation": {
"transport": {
"_id": "604b61b6aad5fab0f3c0d40d",
"transportType": "Bus",
"__v": 0,
"id": "604b61b6aad5fab0f3c0d40d"
},
"tripDate": "2021-03-27T22:00:00.000Z",
"noOfSets": 7,
"transportNotes": "some transportNotes"
},
"bookingStatus": "active",
"_id": "605dc47ed2ed656bce892182",
"salesPerson": "noor smay",
"marketSegment": {
"_id": "604b60796d049aafef1d3b0a",
"marketSegment": "Faceboook",
"__v": 0,
"id": "604b60796d049aafef1d3b0a"
},
"enteredBy": {
"role": "admin",
"_id": "604d1b9767fa82ccffc29acc",
"isAdmin": false,
"name": "ahmed magdy",
"email": "ahmedmagdy#test.com",
"password": "$2a$10$eoYyVF1TTTPQ7pWcCDLVQuvalw8g82yvzzmgD7fvQDH8mCZ4QE30S",
"createdAt": "2021-03-13T20:07:51.428Z",
"updatedAt": "2021-03-13T20:07:51.428Z",
"__v": 0
},
"resDate": "2021-03-26T11:24:46.644Z",
"__v": 0,
"id": "605dc47ed2ed656bce892182"
}
https://docs.mongodb.com/manual/tutorial/update-documents/
updateOne to update 1 record
updateMany for multiple records
await db.collection('inventory').updateOne({ }, // query
{
$set: { 'customerAccount.payStatus': 'New Value' } // update value
}
);
Demo - https://mongoplayground.net/p/iO4I4zVRnOP
Mongo query
db.collection.update({},{
$set: {
"customerAccount.payStatus": "New Value"
}
})

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

Resources