Edit (Update) Specific value in MongoDB Document - node.js

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"
}
})

Related

Select by category and count by status mongodb

I have a list of records and want to group by categories and after this count buy isArchived status.
I'm just starting to learn MongoDB and I can't do the query described below, I would appreciate your tips.
This is peace of data.
[
{
"_id": "63356af2d77a56d764f362e4",
"noteName": "string",
"category": "IDEA",
"content": "string",
"isArchived": true,
"createdAt": "2022-09-29T09:52:50.477Z",
"updatedAt": "2022-09-29T09:52:50.477Z",
"__v": 0
},
{
"_id": "63356afad77a56d764f362ea",
"noteName": "string",
"category": "IDEA",
"content": "string",
"isArchived": false,
"createdAt": "2022-09-29T09:52:58.765Z",
"updatedAt": "2022-09-29T09:52:58.765Z",
"__v": 0
},
{
"_id": "63356afbd77a56d764f362ee",
"noteName": "string",
"category": "IDEA",
"content": "string",
"isArchived": false,
"createdAt": "2022-09-29T09:52:59.180Z",
"updatedAt": "2022-09-29T09:52:59.180Z",
"__v": 0
},
{
"_id": "63356b04d77a56d764f362f4",
"noteName": "string",
"category": "TASK",
"content": "string",
"isArchived": false,
"createdAt": "2022-09-29T09:53:08.261Z",
"updatedAt": "2022-09-29T09:53:08.261Z",
"__v": 0
},
{
"_id": "63356b09d77a56d764f362fc",
"noteName": "string",
"category": "TASK",
"content": "string",
"isArchived": true,
"createdAt": "2022-09-29T09:53:13.980Z",
"updatedAt": "2022-09-29T09:53:13.980Z",
"__v": 0
},
{
"_id": "63356b0ad77a56d764f362fe",
"noteName": "string",
"category": "TASK",
"content": "string",
"isArchived": true,
"createdAt": "2022-09-29T09:53:14.445Z",
"updatedAt": "2022-09-29T09:53:14.445Z",
"__v": 0
}]
This is request
getStats() {
const stats = this.noteModel
.aggregate([
{
$group: {
_id: {
category: '$category',
isArchived: '$isArchived',
},
count: {
$sum: 1,
},
},
},
{ $sort: { _id: 1 } },
])
.project({
_id: 0,
category: '$_id.category',
isArchived: '$_id.isArchived',
average: 1,
count: '$count',
});
return stats;
}
Now I receive like this
[
{
"category": "IDEA",
"isArchived": false,
"count": 5
},
{
"category": "IDEA",
"isArchived": true,
"count": 3
},
{
"category": "QUOTE",
"isArchived": false,
"count": 4
},
{
"category": "QUOTE",
"isArchived": true,
"count": 3
},
{
"category": "RANDOM THOUGHT",
"isArchived": false,
"count": 2
},
{
"category": "RANDOM THOUGHT",
"isArchived": true,
"count": 3
}....
]
But I want to receive it like this
[
{
"category": "IDEA",
"archived": 5,
"unArchived": 3
},
{
"category": "QUOTE",
"archived": 5,
"unArchived": 3
},
{
"category": "RANDOM THOUGHT",
"archived": 2,
"unArchived": 3
},
{
"category": "TASK",
"archived": 3,
"unArchived": 3
},
]
What should be changed in the query to get the required view?
Group by category only and calculate the archived and unArchived counts by checking the condition,
archived condition is if isArchived is true then return 1 otherwise 0
unArchived condition is if isArchived is true then return 0 otherwise 1
const stats = this.noteModel.aggregate([
{
$group: {
_id: "$category",
archived: {
$sum: { $cond: ["$isArchived", 1, 0] }
},
unArchived: {
$sum: { $cond: ["$isArchived", 0, 1] }
}
}
},
{ $sort: { _id: 1 } }
])
Playground

Aggregation query

Node js using mongoose as ORM. I have set of documents like below
I want to calculate the average time for createdAt in ISO String(format) field in duration of hours on
grouping the category field. I have tried many ways to use aggregate but couldn't get the result.
[{
"_id": {
"$oid": "62dfc2cf25735e8b1b475ff1"
},
"numLikes": 0,
"numViews": 0,
"numShares": 0,
"hasUserLiked": false,
"title": "sample-broadcast",
"description": "broadcast-dewscription",
"projectId": {
"$oid": "62d903a5dade1714382b27af"
},
"content": [
{
"_id": {
"$oid": "62dfc2cf25735ee18d475ff2"
},
"downloadLink": "https://builder-broadcast-media.s3.ap-south-1.amazonaws.com/builder-broadcast-media/51daead4-1134-4921-a544-fea845f03d1c/uploadbroadcast/1658831544",
"label": "lance-anderson-QdAAasrZhdk-unsplash (1).jpg",
"contentType": "jpeg"
}
],
"delivery": "scheduleBroadcast",
"category": "GENERAL_UPDATES",
"groupId": "51daead4-1134-4921-a544-fea845f03d1c",
"author": {
"userId": "83314517-9326-430f-9c4e-8fedb050e6b0",
"profilePic": "https://builder-broadcast-media.s3.ap-south-1.amazonaws.com/builder-broadcast-media/4f670832-dfd7-43ee-a6ad-e2f43f48df6a/uploadprofilepic/1658239806",
"name": "Biswajit Rout"
},
"projectLogo": "https://builder-broadcast-media.s3.ap-south-1.amazonaws.com/builder-broadcast-media/4f670832-dfd7-43ee-a6ad-e2f43f48df6a/uploadcompanylogo%2A/1658239764",
"createdAt": {
"$date": {
"$numberLong": "1658831567577"
}
},
"updatedAt": {
"$date": {
"$numberLong": "1658831567577"
}
},
"__v": 0
},{
"_id": {
"$oid": "62dfebae25735e015f476dfb"
},
"numLikes": 0,
"numViews": 0,
"numShares": 0,
"hasUserLiked": false,
"title": "testing-broadcast",
"description": "testing-description",
"projectId": {
"$oid": "62d903a5dade1714382b27af"
},
"content": [
{
"_id": {
"$oid": "62dfebae25735e291c476dfc"
},
"downloadLink": "https://builder-broadcast-media.s3.ap-south-1.amazonaws.com/builder-broadcast-media/51daead4-1134-4921-a544-fea845f03d1c/projectimages0/1658842001",
"label": "lance-anderson-QdAAasrZhdk-unsplash (1).jpg",
"contentType": "jpeg"
},
{
"_id": {
"$oid": "62dfebae25735e0321476dfd"
},
"downloadLink": "https://builder-broadcast-media.s3.ap-south-1.amazonaws.com/builder-broadcast-media/51daead4-1134-4921-a544-fea845f03d1c/projectimages1/1658842024",
"label": "Get_Started_With_Smallpdf.pdf",
"contentType": "pdf"
}
],
"delivery": "immediate",
"link": "http://localhost:3000",
"category": "GENERAL_UPDATES",
"groupId": "51daead4-1134-4921-a544-fea845f03d1c",
"author": {
"userId": "83314517-9326-430f-9c4e-8fedb050e6b0",
"profilePic": "https://builder-broadcast-media.s3.ap-south-1.amazonaws.com/builder-broadcast-media/4f670832-dfd7-43ee-a6ad-e2f43f48df6a/uploadprofilepic/1658239806",
"name": "Biswajit Rout"
},
"projectLogo": "https://builder-broadcast-media.s3.ap-south-1.amazonaws.com/builder-broadcast-media/4f670832-dfd7-43ee-a6ad-e2f43f48df6a/uploadcompanylogo%2A/1658239764",
"createdAt": {
"$date": {
"$numberLong": "1658842030827"
}
},
"updatedAt": {
"$date": {
"$numberLong": "1658842030827"
}
},
"__v": 0
},{
"_id": {
"$oid": "62e144677fc76b0373f40152"
},
"numLikes": 0,
"numViews": 0,
"numShares": 0,
"hasUserLiked": false,
"title": "Broker Offer-1",
"description": "50% off on the membership for early birds. \n\nOffer Applied to first fifty users only",
"projectId": {
"$oid": "62d903a5dade1714382b27af"
},
"content": [
{
"_id": {
"$oid": "62e144677fc76b2b79f40153"
},
"downloadLink": "https://builder-broadcast-media.s3.ap-south-1.amazonaws.com/builder-broadcast-media/51daead4-1134-4921-a544-fea845f03d1c/projectimages0/1658930275",
"label": "50-off-PNG-Picture.png",
"contentType": "png"
}
],
"delivery": "immediate",
"link": "",
"category": "OFFER_BROKERS",
"groupId": "51daead4-1134-4921-a544-fea845f03d1c",
"author": {
"userId": "83314517-9326-430f-9c4e-8fedb050e6b0",
"profilePic": "https://builder-broadcast-media.s3.ap-south-1.amazonaws.com/builder-broadcast-media/4f670832-dfd7-43ee-a6ad-e2f43f48df6a/uploadprofilepic/1658239806",
"name": "Biswajit Rout"
},
"projectLogo": "https://builder-broadcast-media.s3.ap-south-1.amazonaws.com/builder-broadcast-media/4f670832-dfd7-43ee-a6ad-e2f43f48df6a/uploadcompanylogo%2A/1658239764",
"createdAt": {
"$date": {
"$numberLong": "1658930279871"
}
},
"updatedAt": {
"$date": {
"$numberLong": "1658930279871"
}
},
"__v": 0
}]
My expected result should be like this
{
OFFER_BROKERS: 5 <hrs>,
GENERAL_UPDATES : 4 <hrs>
}
Do you want to convert milliseconds to real time and give it to orm

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} })

Retrieve object information within an array with mongoose

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();

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