admin管理员组文章数量:1315061
I've got a MongoDB document which has records that looks like this:
[
{ _id: id, category_name: 'category1', parent_category: null },
{ _id: id, category_name: 'category2', parent_category: null },
{ _id: id, category_name: 'subcategory1', parent_category: id_parent_1 },
{ _id: id, category_name: 'subcategory2', parent_category: id_parent_1 },
{ _id: id, category_name: 'subcategory3', parent_category: id_parent_2 },
{ _id: id, category_name: 'subcategory4', parent_category: id_parent_2 }
]
As you can see, I'm storing categories with a parent_category
of null
, and subcategories have the parent category's ID. What I'm looking for is to group these into some kind of format like this:
[
{ category_name: 'category1', categories: [
{ category_name: 'subcategory1', _id: id },
{ category_name: 'subcategory2', _id: id }
]
},
{ category_name: 'category2', categories: [
{ category_name: 'subcategory3', _id: id },
{ category_name: 'subcategory4', _id: id }
]
}
]
So basically group the parent categories with an array with their child categories. I'm using Mongoose. I tried using the aggregation framework MongoDB provides but I can't get the desired result. :(
I have access to modify the schema in any way that could be needed!
Thanks in advance!
I've got a MongoDB document which has records that looks like this:
[
{ _id: id, category_name: 'category1', parent_category: null },
{ _id: id, category_name: 'category2', parent_category: null },
{ _id: id, category_name: 'subcategory1', parent_category: id_parent_1 },
{ _id: id, category_name: 'subcategory2', parent_category: id_parent_1 },
{ _id: id, category_name: 'subcategory3', parent_category: id_parent_2 },
{ _id: id, category_name: 'subcategory4', parent_category: id_parent_2 }
]
As you can see, I'm storing categories with a parent_category
of null
, and subcategories have the parent category's ID. What I'm looking for is to group these into some kind of format like this:
[
{ category_name: 'category1', categories: [
{ category_name: 'subcategory1', _id: id },
{ category_name: 'subcategory2', _id: id }
]
},
{ category_name: 'category2', categories: [
{ category_name: 'subcategory3', _id: id },
{ category_name: 'subcategory4', _id: id }
]
}
]
So basically group the parent categories with an array with their child categories. I'm using Mongoose. I tried using the aggregation framework MongoDB provides but I can't get the desired result. :(
I have access to modify the schema in any way that could be needed!
Thanks in advance!
Share Improve this question edited Sep 22, 2017 at 18:01 CommunityBot 11 silver badge asked Aug 23, 2015 at 10:11 pmerinopmerino 6,13011 gold badges60 silver badges77 bronze badges 5- Why did you designed your document that way at first place? maybe you can redesign you mongoose schemma and make some methods to validate the parent_id to assign the subcategories – Jose Osorio Commented Aug 23, 2015 at 14:22
- Is it just two levels of categories? can your subcategories have their own subcategories? – Yaron Schwimmer Commented Aug 24, 2015 at 14:35
- @JoseOsorio I don't really understand what you mean – pmerino Commented Aug 24, 2015 at 15:43
- @yarons yes, it'll be just two levels, category and subcategory – pmerino Commented Aug 24, 2015 at 15:44
- 1 Look at this category tree library for mongoose: github./incrediblesound/category-tree . Here a blog post from the author: incrediblesound.github.io/blog/2014/07/27/… – lifeisfoo Commented Aug 25, 2015 at 19:03
4 Answers
Reset to default 5 +50It seems like you're treating Mongo like an relational database (separating all these fields and bringing them together with a query). What you should do is rebuild your Schema. For example:
var CategorySchema = new Schema({
category_name: String,
subCategories:[subCategorySchema]
}
var subCategorySchema = new Schema({
category_name: String
})
This way when you need to query the collection it's a simple
db.find({category_name: "name of the category"}, function(){})
to get everything you need.
Just in case: you can add the sub categories to the array with simple updates. Read this for more info.
Please try this if Your schema is not changed:
var MongoClient = require('mongodb').MongoClient
//connect away
MongoClient.connect('mongodb://127.0.0.1:27017/test', function(err, db) {
if (err) throw err;
console.log("Connected to Database");
//simple json record
var document = [];
//insert record
//db.data.find({"parent_category":null }).forEach(function(data) {print("user: " + db.data.findOne({"parent_category":data._id })) })
db.collection('data').find({"parent_category":null }, function(err, parentrecords) {
if (err) throw err;
var cat ={};
parentrecords.forEach(function(data){
cat["category_name"] = data["category_name"];
db.collection('data').find({"parent_category":data._id },function(err, childrecords) {
var doc = [];
childrecords.forEach(function(childdata){
doc.push(childdata);
},function(){
cat["categories"] = doc;
document.push(cat);
console.log(document);
});
});
});
});
});
If you want to find out expected results without changing schema then you basically follow some plex mongo aggregation
query. For finding output I follow following steps :
- First in
$project
checkparent_category
equalsnull
if true then add_id
else addparent_category
. - Now document structure looks like with new
key name as parent_id
presents and group byparent_id
and push remaining data likecategory_name and parent_category
. - After that use $setDifference and $setIntersection to differentiate parent data and child data.
- And in finally
unwind
only single array objects so this single array object and used project for showing only those fields which to display.
Check working aggregation query as below :
db.collectionName.aggregate({
"$project": {
"parent_id": {
"$cond": {
"if": {
"$eq": ["$parent_category", null]
},
"then": "$_id",
"else": "$parent_category"
}
},
"category_name": 1,
"parent_category": 1
}
}, {
"$group": {
"_id": "$parent_id",
"categories": {
"$push": {
"category_name": "$category_name",
"parent_category": "$parent_category"
}
},
"parentData": {
"$push": {
"$cond": {
"if": {
"$eq": ["$parent_category", null]
},
"then": {
"category_name": "$category_name",
"parent_category": "$parent_category"
},
"else": null
}
}
}
}
}, {
"$project": {
"findParent": {
"$setIntersection": ["$categories", "$parentData"]
},
"categories": {
"$setDifference": ["$categories", "$parentData"]
}
}
}, {
"$unwind": "$findParent"
}, {
"$project": {
"category_name": "$findParent.category_name",
"categories": 1
}
}).pretty()
In order to group records by a field try using $group in Aggreegation.This worked for me.
Example
db.categories.aggregate(
[
{ $group : { _id : {category_name:"$category_name"}, categories: { $push: {category_name:"$category_name",_id:"$_id"} } } }
]
)
Reference: MongoDB Aggregation
Hope this works.
本文标签: javascriptHow to group records by a field in MongooseStack Overflow
版权声明:本文标题:javascript - How to group records by a field in Mongoose? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741972008a2407897.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论