I have an product option schema where I have chield material and add-on type
Product_options
const productOptionsSchema = new mongoose.Schema({
category: [{
value: { type: String },
display: { type: Number },
display_order: { type: String },
categoryImage: { type: String },
parent_id: { type: mongoose.Schema.Types.ObjectId },
parent_name: { type: String }
}],
material: [{
value: { type: String },
display: { type: Number },
display_order: { type: String },
price: { type: String }
}],
addon_type: [{
// addon_id: {
type: mongoose.Schema.Types.ObjectId,
ref: 'AddOnDetails'
// }
}],
design: [{
// design_id: {
type: mongoose.Schema.Types.ObjectId,
ref: 'DesignDetails'
// }
}]
}, {
timestamps: true
})
const Product_options = mongoose.model('Product_options', productOptionsSchema)
i want to add one more key 'isChildExist' if have any chield of category have parent_id == parent_id . my node js code is
const cat = await Product_options.aggregate( [
{
$unwind: {
path: "$category",
preserveNullAndEmptyArrays: true
}
},
{
$lookup: {
from: 'Product_options.category',
localField: '_id',
foreignField: 'parent_id',
as: 'category.isChildExist'
}
},
{
"$project": {
"_id": 0,
"category": 1,
}
}
] );
res.json({
msg: 'Success!',
cat
})
my current response is whenre isChildExist is blank :
{
"msg": "Success!",
"cat": [
{
"category": {
"value": "Rudraksha",
"display": 1,
"display_order": "",
"categoryImage": "",
"parent_id": null,
"parent_name": null,
"_id": "63aeac69f969cf78856b7db9",
"isChildExist": []
}
},
{
"category": {
"value": "Bead Bracelet",
"display": 1,
"display_order": "",
"categoryImage": "",
"parent_id": null,
"parent_name": null,
"_id": "63aeae05f969cf78856b80b2",
"isChildExist": []
}
},
{
"category": {
"value": "Gemstones",
"display": 1,
"display_order": "1",
"categoryImage": "",
"parent_id": null,
"parent_name": null,
"_id": "63aeb968f969cf78856b8cd9",
"isChildExist": []
}
},
{
"category": {
"value": "Natural Yellow Sapphire - Pukhraj ",
"display": 1,
"display_order": "1",
"categoryImage": "",
"parent_id": "63aeb968f969cf78856b8cd9",
"parent_name": "Gemstones",
"_id": "63aec39bf969cf78856bb9c3",
"isChildExist": []
}
},
{
"category": {
"value": "Natural Blue Sapphire - Neelam",
"display": 1,
"display_order": "1",
"categoryImage": "",
"parent_id": "63aeb968f969cf78856b8cd9",
"parent_name": "Gemstones",
"_id": "63aebe42f969cf78856b9fae",
"isChildExist": []
}
},
{
"category": {
"value": "Natural Ruby - Manik ",
"display": 1,
"display_order": "",
"categoryImage": "",
"parent_id": "63aeb968f969cf78856b8cd9",
"parent_name": "Gemstones",
"_id": "63aebe54f969cf78856b9fd9",
"isChildExist": []
}
},
{
"category": {
"value": "Natural Hessonite - Gomed",
"display": 1,
"display_order": "",
"categoryImage": "",
"parent_id": "63aeb968f969cf78856b8cd9",
"parent_name": "Gemstones",
"_id": "63aebe83f969cf78856ba076",
"isChildExist": []
}
},
{
"category": {
"value": "Natural Coral - Moonga ",
"display": 1,
"display_order": "",
"categoryImage": "",
"parent_id": "63aeb968f969cf78856b8cd9",
"parent_name": "Gemstones",
"_id": "63aebe9ff969cf78856ba0a8",
"isChildExist": []
}
},
{
"category": {
"value": "Natural Emerald - Panna ",
"display": 1,
"display_order": "",
"categoryImage": "",
"parent_id": "63aeb968f969cf78856b8cd9",
"parent_name": "Gemstones",
"_id": "63aebeb5f969cf78856ba0de",
"isChildExist": []
}
}
]
}
i expect isChildExist have data in gemstone but current is blank array
{
"category": {
"value": "Gemstones",
"display": 1,
"display_order": "1",
"categoryImage": "",
"parent_id": null,
"parent_name": null,
"_id": "63aeb968f969cf78856b8cd9",
"isChildExist": [
{
"value": "Natural Yellow Sapphire - Pukhraj ",
"display": 1,
"display_order": "1",
"categoryImage": "",
"parent_id": "63aeb968f969cf78856b8cd9",
"parent_name": "Gemstones",
"_id": "63aec39bf969cf78856bb9c3",
"child": []
},{
"value": "Natural Blue Sapphire - Neelam",
"display": 1,
"display_order": "1",
"categoryImage": "",
"parent_id": "63aeb968f969cf78856b8cd9",
"parent_name": "Gemstones",
"_id": "63aebe42f969cf78856b9fae",
"child": []
}
]
}
},
Problem is in $lookup
Try this code:
const cat = await Product_options.aggregate([{
$unwind: {
path: "$category",
preserveNullAndEmptyArrays: true
}
},
{
$lookup: {
from: 'Product_options',
let: {
category_id: "$category._id"
},
pipeline: [{
$match: {
$expr: {
$and: [{
$eq: ["$category.parent_id", "$$category_id"]
}, ]
}
}
},
{
$project: {
_id: 0,
category: 1,
}
}
],
as: "category.isChildExist"
}
},
{
$project: {
_id: 0,
category: 1
}
}
]);
Related
I'm new to mongoose, I'm confuse while create the query. Can you help me?
I have a movie document like this :
"movies": [
{
"id": "635611395a71beb6c5bf0b4d",
"title": "Mission: Impossible - Fallout",
"createdAt": "2022-10-24T04:14:54.445Z",
"cast": [
{
"actor": "635350c581d5b60383f0c4be",
"roleAs": "Ethan Hunt",
"leadActor": true,
"_id": "635658c18b9e50facd7f1fd1"
},
{
"actor": "63560bf55a71beb6c5bf0b1f",
"roleAs": "Ilsa Faust",
"leadActor": false,
"_id": "635658c18b9e50facd7f1fd2"
}
],
"poster": {
"url": "https://res.cloudinary.com/debfn35m1/image/upload/v1666603204/vczxb7lgbonjn8ydsyep.jpg",
"public_id": "vczxb7lgbonjn8ydsyep",
"responsive": [
"https://res.cloudinary.com/debfn35m1/image/upload/c_scale,w_640/v1666603204/vczxb7lgbonjn8ydsyep.jpg",
"https://res.cloudinary.com/debfn35m1/image/upload/c_scale,w_50/v1666603204/vczxb7lgbonjn8ydsyep.jpg"
]
},
"reviews": {
"ratingAvg": "5.0",
"reviewCount": 2
}
},
{
"id": "635614855a71beb6c5bf0bdc",
"title": "Spider-Man: No Way Home",
"createdAt": "2022-10-24T04:28:58.286Z",
"cast": [
{
"actor": "635350a881d5b60383f0c4b8",
"roleAs": "Peter Parker",
"leadActor": true,
"_id": "636a2d6520cf4cf14a11ef95"
},
{
"actor": "635611eb5a71beb6c5bf0b99",
"roleAs": "MJ",
"leadActor": false,
"_id": "636a2d6520cf4cf14a11ef96"
}
],
"poster": {
"url": "https://res.cloudinary.com/debfn35m1/image/upload/v1667902823/tajzr9hpulvzqoytgpxu.jpg",
"public_id": "tajzr9hpulvzqoytgpxu",
"responsive": [
"https://res.cloudinary.com/debfn35m1/image/upload/c_scale,w_640/v1667902823/tajzr9hpulvzqoytgpxu.jpg",
"https://res.cloudinary.com/debfn35m1/image/upload/c_scale,w_470/v1667902823/tajzr9hpulvzqoytgpxu.jpg",
"https://res.cloudinary.com/debfn35m1/image/upload/c_scale,w_50/v1667902823/tajzr9hpulvzqoytgpxu.jpg"
]
},
"reviews": {
"ratingAvg": "8.0",
"reviewCount": 2
}
},
This is my desired result:
{
"id": "635611395a71beb6c5bf0b4d",
"title": "Mission: Impossible - Fallout",
"createdAt": "2022-10-24T04:14:54.445Z",
"cast": [
{
"actor": "635350c581d5b60383f0c4be",
"roleAs": "Ethan Hunt",
"leadActor": true,
"_id": "635658c18b9e50facd7f1fd1"
},
{
"actor": "63560bf55a71beb6c5bf0b1f",
"roleAs": "Ilsa Faust",
"leadActor": false,
"_id": "635658c18b9e50facd7f1fd2"
}
],
"poster": {
"url": "https://res.cloudinary.com/debfn35m1/image/upload/v1666603204/vczxb7lgbonjn8ydsyep.jpg",
"public_id": "vczxb7lgbonjn8ydsyep",
"responsive": [
"https://res.cloudinary.com/debfn35m1/image/upload/c_scale,w_640/v1666603204/vczxb7lgbonjn8ydsyep.jpg",
"https://res.cloudinary.com/debfn35m1/image/upload/c_scale,w_50/v1666603204/vczxb7lgbonjn8ydsyep.jpg"
]
},
"reviews": {
"ratingAvg": "5.0",
"reviewCount": 2
}
},
Im trying to write a filter function to get all movie that has Tom Cruise with actorId as a parameter but cannot get the result.
Can someone please help me with this ?
Since your actor id is inside a cast array with key actor you must specify your key while match, check the updated code below
exports.actorAggregation = (actorId) => {
return [
{
$lookup: {
from: "Movie",
localField: "cast",
foreignField: "_id",
as: "actorFilter",
},
},
{ $unwind: "$cast" },
{
$match: {
"cast.actor._id": { $in: [actorId] }, // or "cast.actor": { $in: [actorId] },
status: { $eq: "public" },
},
},
{
$project: {
title: 1,
poster: "$poster.url",
responsivePosters: "$poster.responsive",
createdAt: "$createdAt",
},
},
];
};
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
Ok so i've tired many things to solve this issue, what im facing with is, i have this document
{
"_id": "5ef9c6a9691c33e13c455413",
"tags": [
"chicken wings",
"pizza",
"burgers"
],
"shopName": "Emily",
"isOpen": true,
"address": "919 Fulton St, Brooklyn, NY 11238",
"image": "random-2.jpg",
"category": "Asian",
"stars": [
12,
22,
32,
0,
0
],
"logo": "logo.png",
"phone": "+96501234567",
"totalCompletedOrders": 22,
"eta": "60",
"products": [
{
...
"category": "Appeteasers"
},
{
...
"category": "Appeteasers"
},
{
...
"category": "Appeteasers"
},
{
...
"category": "Appeteasers"
},
{
...
"category": "Appeteasers"
},
{
...
"category": "Appeteasers"
},
{
...
"category": "Appeteasers"
},
{
...
"category": "Fino sides"
},
{
...
"category": "Fino sides"
},
{
...
"category": "Fino sides"
},
{
...
"category": "Fino sides"
},
{
...
"category": "Peri-peri chicken"
},
{
...
"category": "Peri-peri chicken"
},
{
...
"category": "Peri-peri chicken"
},
{
...
"category": "Peri-peri chicken"
},
{
...
"category": "Peri-peri chicken"
},
{
...
"category": "Peri-peri chicken"
},
{
...
"category": "Peri-peri chicken"
},
{
...
"category": "Peri-peri chicken"
},
{
...
"category": "Peri-peri chicken"
},
{
...
"category": "Peri-peri chicken"
},
{
...
"category": "Peri-peri chicken"
},
{
...
"category": "Peri-peri chicken"
},
{
...
"category": "Peri-peri chicken"
},
{
...
"category": "Peri-peri chicken"
},
{
...
"category": "Peri-peri chicken"
},
{
...
"category": "Peri-peri chicken"
},
{
...
"category": "Peri-peri chicken"
}
]
}
so my issue is i need to group the products array and make it look into something like this or close to it
{
"_id": "5ef9c6a9691c33e13c455413",
"tags": [
"chicken wings",
"pizza",
"burgers"
],
"shopName": "Emily",
"isOpen": true,
"address": "919 Fulton St, Brooklyn, NY 11238",
"image": "random-2.jpg",
"category": "Asian",
"stars": [
12,
22,
32,
0,
0
],
"logo": "logo.png",
"phone": "+96501234567",
"totalCompletedOrders": 22,
"eta": "60",
"products": [{
category: "Appeteasers",
products:[...all Appeteasers chicken here]
},{
category: "Fino sides chicken",
products:[...all Fino sides chicken here]
},{
category: "Peri-peri chicken",
products:[...all Peri-peri chicken here]
}]
}
what i've tired is
Store.aggregate([
{$match:{ _id: id}, },
{ $unwind: "$products" },
{
$group : {
_id: "$products.category",
"products" : {"$addToSet": "$products"},
}
},
]);
and i got so close to the result but i the root fields are not included
[
{
"_id": "Peri-peri chicken",
"products": [...]
},
{
"_id": "Appeteasers",
"products": [...]
},
{
"_id": "Fino sides",
"products": [...]
}
]
would love some help, thank you
To get all other keys in the document you have mention the key in $project, then only they will be accessible. In below code, I have just added three of them to show how it has to be done. You can add rest of them.
Store.aggregate([
{
$match:{ _id: id}
},
{
$project: { products: "$products", shopName: "$shopName", stars: "$stars", tags: "$tags", }
},
{
$unwind: "$products"
},
{
$group : {
_id: "$products.category",
"products" : {"$addToSet": "$products"},
"tags": {"$addToSet": "$tags"},
"stars": {"$addToSet": "$stars"},
"shopName": {"$first": "$shopName"}
}
},
{
$project: {products: "$products", tags: "$tags", shopName: "$shopName", stars: "$stars" }
},
]);
{
"success": true,
"message": "Result",
"data": [
{
"Here": [
{
"_id": "5ee97ee7f25d1c1482717bdf",
"email": "test1#test.io",
"profileImages": [],
"username": "test1",
"birthday": "2020-06-11T10:11:32.000Z",
"phoneNumber": "+910000000000",
"location": "Test Location",
"firstName": "test1",
"lastName": "test1",
}
]
},
{
"Here": [
{
"_id": "5ee97ef2f25d1c1482717be1",
"email": "test2#test.io",
"profileImages": [],
"username": "test2",
"birthday": "2020-06-11T10:11:32.000Z",
"phoneNumber": "+910000000000",
"location": "Test Location"
}
]
}
],
}
What I am expecting is this
{
"success": true,
"message": "Result",
data: [
{
"_id": "5ee97ee7f25d1c1482717bdf",
"email": "test1#test.io",
"profileImages": [],
"username": "test1",
"birthday": "2020-06-11T10:11:32.000Z",
"phoneNumber": "+910000000000",
"location": "Test Location",
"firstName": "test1",
"lastName": "test1"},
{
"_id": "5ee97ef2f25d1c1482717be1",
"email": "test2#test.io",
"profileImages": [],
"username": "test2",
"birthday": "2020-06-11T10:11:32.000Z",
"phoneNumber": "+910000000000",
"location": "Test Location"
}
]
}
Query I am using is for this response is below using aggregation in mongodb, lookup and project which is leading me to the some undesired response
db.collections.aggregate( [
{
$lookup: {
from: 'users',
as: 'Here',
let: {
whoDid: '$whoDid'
},
pipeline: [
{
"$match": { "$expr": { "$eq": ["$_id", "$$whoDid"] } }
},
{
$project: {
_id: 1,
email: 1,
profileImages: 1,
username: 1,
birthday: 1,
phoneNumber: 1,
firstName: 1,
lastName: 1,
fullName: 1,
// age: {$year: "$birthday"}
age: {
$divide: [{ $subtract: [new Date(), "$birthday"] },
(31558464000)]
}
}
}
],
}
},
{
$project:{
Here:1,
_id:0
}
} ,
])
who did table is one of the collection I have where I have stored the user Id and later I am populating the data using lookup
{
"_id" : ObjectId("5ee988eb1aac0022e15dbb7b"),
"whoDid" : ObjectId("5ee97ef2f25d1c1482717be1"),
"toWhomDid" : ObjectId("5ee97ec0f25d1c1482717bdd"),
"modified_at" : ISODate("2020-06-17T03:07:23.217Z"),
"created_at" : ISODate("2020-06-17T03:07:23.217Z"),
"__v" : 0
}
{
"_id" : ObjectId("5ee988eb1aac0022e15dbb7c"),
"whoDid" : ObjectId("5ee97ec0f25d1c1482717bdd"),
"toWhomDid" : ObjectId("5ee97ef2f25d1c1482717be1"),
"modified_at" : ISODate("2020-06-17T03:07:23.220Z"),
"created_at" : ISODate("2020-06-17T03:07:23.220Z"),
"__v" : 0
}
Can anyone suggest me any better option so that I can get a desired respose?
It is possible to use reduce method:
obj.data = obj.data.reduce((a, c) => {
a.push(...c.Here);
return a;
}, [])
An example:
let obj = {
"success": true,
"message": "Result",
"data": [ {
"Here": [ {
"_id": "5ee97ee7f25d1c1482717bdf", "email": "test1#test.io",
"profileImages": [], "username": "test1",
"birthday": "2020-06-11T10:11:32.000Z", "phoneNumber": "+910000000000", "location": "Test Location",
"firstName": "test1", "lastName": "test1",
}
]
},
{
"Here": [ {
"_id": "5ee97ef2f25d1c1482717be1",
"email": "test2#test.io",
"profileImages": [],
"username": "test2",
"birthday": "2020-06-11T10:11:32.000Z",
"phoneNumber": "+910000000000",
"location": "Test Location"
}
]
}
]
};
obj.data = obj.data.reduce((a, c) => {
a.push(...c.Here);
return a;
}, [])
console.log(obj);
Add these extra steps into your aggregation pipeline:
{
$unwind: "$Here"
},
{
$replaceWith: "$Here"
}
MongoPlayground
Note: You can replace $project: { _id: 1, email: 1, ... to this:
{
$addFields:{
age: {
$divide: [{ $subtract: [new Date(), "$birthday"] },(31558464000)]
}
}
}
I have one collection called "location". in this collection all child and parent collection are stores. now I want to create a query who returns me parent to child comma separated string.
Collection
businessId: { type: mongoose.Schema.Types.ObjectId, ref: 'admin' },
parentId: { type: mongoose.Schema.Types.ObjectId, ref: 'location' },
name: { type: String },
image: { type: String },
imageManipulation: { type: String },
locationColor: [{ range: { type: String }, color: { type: String } }],
area: {},
settings: {},
status: { type: String, enum: [0, 1], default: 1 },
isChild: { type: String, enum: [0, 1] },
parentPosition: { type: String }
In the above collection, you can see parentId field. if the location is a child then it have parentId. if the location is a parent then parentId will null. parent location can N level child location.
Collection Data
[{
"_id": ObjectId("5ce4f84547e90a0b9c3c4763"),
"name": "Test",
"settings": {
"zoom": "3",
"positionX": "69",
"positionY": "69",
"width": "500",
"height": "334"
},
"parentId": null,
"image": "1558509637101.jpg",
"status": "0",
"businessId": ObjectId("5cbd61dc3b56b902284ea388"),
"locationColor": [],
"updatedAt": ISODate("2019-05-22T12:59:26.013Z"),
"createdAt": ISODate("2019-05-22T07:20:37.112Z"),
"__v": 0
},
{
"_id": ObjectId("5ce50caf09359e1b8ccf5c79"),
"name": "Test sub 1",
"settings": {
"zoom": "3",
"positionX": "48",
"positionY": "3",
"width": "500",
"height": "334"
},
"area": "",
"parentId": ObjectId("5ce4f84547e90a0b9c3c4763"),
"image": "1558514863396.jpg",
"status": "0",
"businessId": ObjectId("5cbd61dc3b56b902284ea388"),
"locationColor": [],
"updatedAt": ISODate("2019-05-22T12:59:21.883Z"),
"createdAt": ISODate("2019-05-22T08:47:43.421Z"),
"__v": 0
},
{
"_id": ObjectId("5ce53977e46da33e6cfdd9d1"),
"name": "Test Sub 2",
"settings": {
"zoom": "5",
"positionX": "0",
"positionY": "0",
"width": "500",
"height": "334"
},
"area": "",
"parentId": ObjectId("5ce50caf09359e1b8ccf5c79"),
"image": "1558526327126.jpg",
"businessId": ObjectId("5cbd61dc3b56b902284ea388"),
"locationColor": [],
"updatedAt": ISODate("2019-05-22T11:58:47.147Z"),
"createdAt": ISODate("2019-05-22T11:58:47.147Z"),
"__v": 0
}]
Expected Result
Test, Test sub 1, Test Sub 2
Expected result in JSON
[{
"_id": ObjectId("5ce4f84547e90a0b9c3c4763"),
"name": "Test",
},
{
"_id": ObjectId("5ce50caf09359e1b8ccf5c79"),
"name": "Test, Test sub 1",
},
{
"_id": ObjectId("5ce53977e46da33e6cfdd9d1"),
"name": "Test, Test sub 1, Test Sub 2",
}]
You basically need $graphLookup for recursive loop over the same collection.
db.location.aggregate([
{ "$graphLookup": {
"from": "location",
"startWith": "$parentId",
"connectFromField": "parentId",
"connectToField": "_id",
"as": "parent"
}},
{ "$project": {
"name": {
"$concat": [
"$name",
{ "$reduce": {
"input": "$parent",
"initialValue": "",
"in": { "$concat": [",", "$$this.name", "$$value"] }
}}
]
}
}}
])
Which will output
[
{
"_id": ObjectId("5ce4f84547e90a0b9c3c4763"),
"name": "Test"
},
{
"_id": ObjectId("5ce50caf09359e1b8ccf5c79"),
"name": "Test sub 1,Test"
},
{
"_id": ObjectId("5ce53977e46da33e6cfdd9d1"),
"name": "Test Sub 2,Test sub 1,Test"
}
]
MongoPlayground