Select by category and count by status mongodb - node.js

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

Related

How to set up aggregation pipeline for specific use case in MongoDB

`I have two collections in MongoDB. One is users and the other is companies. I need to be able to populate the users.endpoints with the endpoints from companies that match ObjectID's which are in the user.endPoints property. It is a bit hard for me to wrap my head around considering there are two steps.
This is the companies collection.
{
"_id": {
"$oid": "63ed39162bfc2cf8065b76cf"
{
"_id": {
"$oid": "63ed39162bfc2cf8065b76cf"
},
"companyName": "Sowegatel",
"amount": 0,
"signalwireSid": "id",
"numbers": [
{
"number": "+12068133580",
"_id": {
"$oid": "63ed39c72bfc2cf8065b76f0"
},
"createdAt": {
"$date": {
"$numberLong": "1676491207931"
}
},
"updatedAt": {
"$date": {
"$numberLong": "1676491207931"
}
}
}
],
"endPoints": [
{
"userName": "4009",
"_id": "fb1d0ef9-c713-400e-a3c9-cbc6823aaf57"
},
{
"userName": "4019",
"_id": "506e710d-14a6-4345-bc89-8488af4cabe4"
},
{
"userName": "4020",
"_id": "c80bd1ab-ca8d-4649-9d35-56d64ef8fab5",
"type": "sip_endpoint"
}
],
"__v": 6
} },
"companyName": "Sowegatel",
"amount": 0,
"signalwireSid": "id",
"numbers": [
{
"number": "+12068133580",
"_id": {
"$oid": "63ed39c72bfc2cf8065b76f0"
},
"createdAt": {
"$date": {
"$numberLong": "1676491207931"
}
},
"updatedAt": {
"$date": {
"$numberLong": "1676491207931"
}
}
}
],
"endPoints": [
{
"userName": "4009",
"_id": "fb1d0ef9-c713-400e-a3c9-cbc6823aaf57"
},
{
"userName": "4019",
"_id": "506e710d-14a6-4345-bc89-8488af4cabe4"
},
{
"userName": "4020",
"_id": "c80bd1ab-ca8d-4649-9d35-56d64ef8fab5",
"type": "sip_endpoint"
}
],
"__v": 6
}
This is the users collection.
{
"_id": {
"$oid": "63ed39162bfc2cf8065b76d2"
},
"firstName": "mark",
"lastName": "thomas",
"email": "mt#st.com",
"password": "",
"companyId": {
"$oid": "63ed39162bfc2cf8065b76cf"
},
"active": true,
"role": "companyAdmin",
"tokens": [],
"__v": 2,
"endpoints": [
// I need to populate to endpoints here!!!! //
"c80bd1ab-ca8d-4649-9d35-56d64ef8fab5"
]
}
I can do a single step aggregation, but this is a little complicated for me.`

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 get the available time slots for particular minutes in a mongodb collection

I am creating a booking system ,which has booking collection like this
{
"_id": {
"$oid": "61cb68eed0a209fa3f76335d"
},
"name": "string",
"vendorId": "string",
"serviceDate": "2021-12-29",
"serviceStartTime": {
"$date": "2021-12-28T19:45:00.000Z"
},
"serviceEndTime": {
"$date": "2021-12-28T21:15:00.000Z"
},
"staffId": "string",
"services": [
[
{
"serviceName": "string",
"servicePrice": "string",
"gender": "string",
"description": "string"
}
]
],
"isAccepted": false,
"isActive": true,
"createdAt": {
"$date": "2021-12-28T19:43:42.953Z"
},
"updatedAt": {
"$date": "2021-12-28T19:43:42.953Z"
},
"__v": 0
}
There can be many bookings like this ,with serviceStart time and serviceEnd time for a particular serviceDate
I want to get the available time slots lets say for 45 minutes between 8 am to 8pm for showing the availability slots in a calendar for particular staffId
Is this possible in mongdb ?.Please help
Expected output
{
slot :"11:00 - 12:00"
}
or
{
slotStartTime :"11:00",
slotEndTime :" 12:00",
}
I don't mind the format ,just need available time slots like start time and end time
Edit
[{
"_id": {
"$oid": "61cb68eed0a209fa3f76335d"
},
"name": "string",
"vendorId": "string",
"serviceDate": "2021-12-29",
"serviceStartTime": {
"$date": "2021-12-28T19:45:00Z"
},
"serviceEndTime": {
"$date": "2021-12-28T21:15:00Z"
},
"staffId": "string",
"services": [
[
{
"serviceName": "string",
"servicePrice": "string",
"gender": "string",
"description": "string"
}
]
],
"isAccepted": false,
"isActive": true,
"createdAt": {
"$date": "2021-12-28T19:43:42.953Z"
},
"updatedAt": {
"$date": "2021-12-28T19:43:42.953Z"
},
"__v": 0
},{
"_id": {
"$oid": "61cb7a9f8be10f47d4089e7b"
},
"name": "string",
"vendorId": "string",
"serviceDate": "2021-12-29",
"serviceStartTime": {
"$date": "2021-12-29T07:45:00Z"
},
"serviceEndTime": {
"$date": "2021-12-29T09:15:00Z"
},
"staffId": "string",
"services": [
[
{
"serviceName": "string",
"servicePrice": "string",
"gender": "string",
"description": "string"
}
]
],
"isAccepted": false,
"isActive": true,
"createdAt": {
"$date": "2021-12-28T20:59:11.638Z"
},
"updatedAt": {
"$date": "2021-12-28T20:59:11.638Z"
},
"__v": 0
}]
Query
match the date "2021-12-29" (put any date)
check hour for both to be >=8 and <=19
map on the range of the 2 dates difference with step 45min
(we need this to get all slots)
reduce to make them pairs
unwind to make each pair separate document
convert the dates to strings in the format hour:min "slot": "15:00 - 15:45"
*instead of 45 you can put the minutes you want like 60,15 etc
Test code here
aggregate(
[{"$match":{"$expr":{"$eq":["$serviceDate", "2021-12-29"]}}},
{"$set":
{"serviceStartTime":
{"$dateFromParts":
{"year":{"$year":"$serviceStartTime"},
"day":{"$dayOfYear":"$serviceStartTime"},
"hour":
{"$switch":
{"branches":
[{"case":{"$lt":[{"$hour":"$serviceStartTime"}, 8]}, "then":8},
{"case":{"$gt":[{"$hour":"$serviceStartTime"}, 19]},
"then":19}],
"default":{"$hour":"$serviceStartTime"}}},
"minute":
{"$switch":
{"branches":
[{"case":{"$lt":[{"$hour":"$serviceStartTime"}, 8]}, "then":0},
{"case":{"$gt":[{"$hour":"$serviceStartTime"}, 19]},
"then":0}],
"default":{"$minute":"$serviceStartTime"}}}}}}},
{"$set":
{"serviceEndTime":
{"$dateFromParts":
{"year":{"$year":"$serviceEndTime"},
"day":{"$dayOfYear":"$serviceEndTime"},
"hour":
{"$switch":
{"branches":
[{"case":{"$lt":[{"$hour":"$serviceEndTime"}, 8]}, "then":8},
{"case":{"$gt":[{"$hour":"$serviceEndTime"}, 19]}, "then":
20}],
"default":{"$hour":"$serviceEndTime"}}},
"minute":
{"$switch":
{"branches":
[{"case":{"$lt":[{"$hour":"$serviceEndTime"}, 8]}, "then":0},
{"case":{"$gt":[{"$hour":"$serviceEndTime"}, 19]}, "then":0}],
"default":{"$minute":"$serviceEndTime"}}}}}}},
{"$set":
{"slots":
{"$map":
{"input":
{"$range":
[0,
{"$subtract":
[{"$add":["$serviceEndTime", {"$multiply":[60, 1000]}]},
"$serviceStartTime"]},
{"$multiply":[45, 60, 1000]}]},
"in":{"$add":["$serviceStartTime", "$$this"]}}}}},
{"$set":
{"slots":
{"$filter":
{"input":"$slots",
"cond":
{"$and":
[{"$gte":[{"$hour":"$$this"}, 8]},
{"$lte":[{"$hour":"$$this"}, 19]}]}}}}},
{"$set":
{"slots":
{"$reduce":
{"input":"$slots",
"initialValue":{"data":[], "prv":null},
"in":
{"$cond":
[{"$eq":["$$value.prv", null]},
{"data":"$$value.data", "prv":"$$this"},
{"data":
{"$concatArrays":
["$$value.data", [["$$value.prv", "$$this"]]]},
"prv":"$$this"}]}}}}},
{"$project":{"_id":0, "staffId":1, "slots":"$slots.data"}},
{"$unwind":"$slots"},
{"$project":
{"staffId":1,
"slot":
{"$concat":
[{"$dateToString":
{"date":{"$arrayElemAt":["$slots", 0]}, "format":"%H:%M"}},
" - ",
{"$dateToString":
{"date":{"$arrayElemAt":["$slots", 1]}, "format":"%H:%M"}}]}}}])

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

$graphLookup return void array

I have below collection:
[{
"_id": "60035d0a1599912a5c814e58",
"idUsuario": "600365521599912a5c814e5e",
"parentNode": "",
"piernaPadre": "",
"estado": "1"
},
{
"_id": "6003827b06b4423c9ca7e6aa",
"idUsuario": "60036e53dda7df34749ebf3a",
"parentNode": "60035d0a1599912a5c814e58",
"piernaPadre": "d",
"estado": 1
},
{
"_id": "60038c92ea7d593fe029cc0f",
"idUsuario": "600382a506b4423c9ca7e6ab",
"parentNode": "6003827b06b4423c9ca7e6aa",
"piernaPadre": "d",
"estado": 1
}]
I need to get the descendants of a node, I'm trying with $graphLookup,
$graphLookup: {
from: "nodoModel",
startWith: "$_id",
connectFromField: "_id",
connectToField: "parentNode",
as: "arrayDes"
}
but does not work, the return is void. Is there a mistake?
Thanks.
EDIT 1
Now I can get a result when try to get de ancestors of a node:
$graphLookup: {
from: "nodos",
startWith: "$_id",
connectFromField: "_id",
connectToField: "nodoPadre",
as: "padre"
}
Whit below result:
[
{
_id: 60035d0a1599912a5c814e58,
idUsuario: '600365521599912a5c814e5e',
parentNode: '',
piernaPadre: '',
estado: '1',
padre: [ [Object] ]
},
{
_id: 6004589436a40941f48121f8,
idUsuario: '600365e9ccf1e51b2cab341f',
parentNode: '60035d0a1599912a5c814e58',
piernaPadre: 'd',
estado: 1,
createdAt: 2021-01-17T15:32:36.986Z,
updatedAt: 2021-01-17T15:32:36.986Z,
__v: 0,
padre: [ [Object] ]
},
{
_id: 6004592936a40941f48121fa,
idUsuario: '6004591536a40941f48121f9',
parentNode: '6004589436a40941f48121f8',
piernaPadre: 'd',
estado: 1,
createdAt: 2021-01-17T15:35:05.626Z,
updatedAt: 2021-01-17T15:35:05.626Z,
__v: 0,
padre: [ [Object] ]
}
]
But I need to get the descendants not the ancestors
EDIT 2
(in the original model parentNode is named nodoPadre)
It is a screenshot of my code:
and that is the console.log:
arrayDes is a void array. I'm using mongoose, maybe it is related with the problem?
EDIT 3
I'm trying to change type of nodoPadre to objectId
Try query to get descendants,
$match put condition
$grouphLookup same as yours
{ $match: { nodoPadre: "" } },
{
$graphLookup: {
from: "collection",
startWith: "$_id",
connectFromField: "_id",
connectToField: "nodoPadre",
as: "arrayDes"
}
}
Playground
For your Second Edit:
Update nodoPadre type to object id type in all documents, and change type in schema to type: mongoose.Types.ObjectId
nodoPadre: {
type: mongoose.Types.ObjectId,
required: [false, '2'],
index: true
}
I had the same issue and finally I resolved it by chnaging the collection name to small letters and it should be plural based on mongodb . Here is my details
Mongoose schema:
const fileFolderSchema = new Schema({
name: String,
parentFolder: {type: Mongoose.Types.ObjectId, ref: "FileFolder"},
path: String,
metadata: {
type: metaDataSchema
}
}, { id: false }).set('toJSON', {
virtuals: true
});
export const FileFolder = Mongoose.model('FileFolder', fileFolderSchema);
Nodejs Method:
folder_tree_structure: async(ctx:any) => {
try {
let treeStructure = await FileFolder.aggregate([
{
$match: {
parentFolder: {
$exists: true
}
}
},
{
$graphLookup: {
from: 'filefolders', // here your collection name is always small letters and plural
startWith: '$_id',
connectFromField: 'parentFolder',
connectToField: 'parentFolder',
maxDepth: 1,
depthField: 'depth',
as: 'TreeResult'
}
}
]);
console.log('tree structure',treeStructure )
ctx.status = 200;
ctx.body = treeStructure;
} catch (err) {
ctx.status = 400;
ctx.body = 'Not found'
}
}
My Nodejs response:
[
{
"_id": "636cd1d2692344da47f3e2f0",
"name": "Folder2",
"path": "files/Folder2",
"metadata": {
"version": 1,
"created_by": "user-1",
"created_on": "2022-11-10T10:26:26.828Z",
"timeout": -1
},
"__v": 0,
"parentFolder": "636cd213692344da47f3e2f5",
"TreeResult": [
{
"_id": "636cd238692344da47f3e301",
"name": "Folder3",
"path": "files/Folder3",
"metadata": {
"version": 1,
"created_by": "user-1",
"created_on": "2022-11-10T10:28:08.655Z",
"timeout": -1
},
"__v": 0,
"parentFolder": "636cd1d2692344da47f3e2f0",
"depth": 0
},
{
"_id": "636d075874867ade3d3c3224",
"name": "images",
"path": "files/images",
"metadata": {
"version": 1,
"created_by": "user-1",
"created_on": "2022-11-10T14:14:48.871Z",
"timeout": -1
},
"__v": 0,
"parentFolder": "636cd1d2692344da47f3e2f0",
"depth": 0
}
]
},
{
"_id": "636cd213692344da47f3e2f5",
"name": "Folder1",
"path": "files/Folder1",
"metadata": {
"version": 1,
"created_by": "user-1",
"created_on": "2022-11-10T10:27:31.600Z",
"timeout": -1
},
"__v": 0,
"parentFolder": "636cd213692344da47f3e2f5",
"TreeResult": [
{
"_id": "636cd213692344da47f3e2f5",
"name": "Folder1",
"path": "files/Folder1",
"metadata": {
"version": 1,
"created_by": "user-1",
"created_on": "2022-11-10T10:27:31.600Z",
"timeout": -1
},
"__v": 0,
"parentFolder": "636cd213692344da47f3e2f5",
"depth": 0
},
{
"_id": "636cd1d2692344da47f3e2f0",
"name": "Folder2",
"path": "files/Folder2",
"metadata": {
"version": 1,
"created_by": "user-1",
"created_on": "2022-11-10T10:26:26.828Z",
"timeout": -1
},
"__v": 0,
"parentFolder": "636cd213692344da47f3e2f5",
"depth": 0
},
{
"_id": "636ce2452e97522606b14b23",
"name": "images",
"path": "files/images",
"metadata": {
"version": 1,
"created_by": "user-1",
"created_on": "2022-11-10T11:36:37.691Z",
"timeout": -1
},
"__v": 0,
"parentFolder": "636cd213692344da47f3e2f5",
"depth": 0
}
]
},
{
"_id": "636cd238692344da47f3e301",
"name": "Folder3",
"path": "files/Folder3",
"metadata": {
"version": 1,
"created_by": "user-1",
"created_on": "2022-11-10T10:28:08.655Z",
"timeout": -1
},
"__v": 0,
"parentFolder": "636cd1d2692344da47f3e2f0",
"TreeResult": []
},
{
"_id": "636ce2452e97522606b14b23",
"name": "images",
"path": "files/images",
"metadata": {
"version": 1,
"created_by": "user-1",
"created_on": "2022-11-10T11:36:37.691Z",
"timeout": -1
},
"__v": 0,
"parentFolder": "636cd213692344da47f3e2f5",
"TreeResult": []
},
{
"_id": "636d075874867ade3d3c3224",
"name": "images",
"path": "files/images",
"metadata": {
"version": 1,
"created_by": "user-1",
"created_on": "2022-11-10T14:14:48.871Z",
"timeout": -1
},
"__v": 0,
"parentFolder": "636cd1d2692344da47f3e2f0",
"TreeResult": []
}
]
Here is mongo play ground link:
https://mongoplayground.net/p/M4pEB34Ozib

Resources