Javascript 如何在Mongoose中按字段对记录进行分组?
我有一个MongoDB文档,其中有如下记录:Javascript 如何在Mongoose中按字段对记录进行分组?,javascript,node.js,mongodb,mongoose,nosql,Javascript,Node.js,Mongodb,Mongoose,Nosql,我有一个MongoDB文档,其中有如下记录: [ { _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, cate
[
{ _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 }
]
[
{ 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 }
]
}
]
如您所见,我正在使用null
的parent\u category
存储类别,子类别具有父类别的ID。我正在寻找的是将这些类别分组为如下某种格式:
[
{ _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 }
]
[
{ 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 }
]
}
]
因此,基本上用一个数组将父类别与其子类别分组。我在用猫鼬。我尝试使用MongoDB提供的聚合框架,但未能获得预期结果:(
我有权以任何可能需要的方式修改模式
提前感谢!您似乎将Mongo视为一个关系数据库(分离所有这些字段并通过查询将它们组合在一起)。您应该做的是重新构建架构。例如:
var CategorySchema = new Schema({
category_name: String,
subCategories:[subCategorySchema]
}
var subCategorySchema = new Schema({
category_name: String
})
这样,当您需要查询集合时,它是一个简单的
db.find({category_name: "name of the category"}, function(){})
得到你需要的一切
以防万一:您可以通过简单的更新将子类别添加到数组中。有关详细信息,请阅读。您似乎将Mongo视为一个关系数据库(将所有这些字段分离,并通过查询将它们组合在一起)。您应该做的是重建架构。例如:
var CategorySchema = new Schema({
category_name: String,
subCategories:[subCategorySchema]
}
var subCategorySchema = new Schema({
category_name: String
})
这样,当您需要查询集合时,它是一个简单的
db.find({category_name: "name of the category"}, function(){})
得到你需要的一切
以防万一:您可以通过简单的更新将子类别添加到数组中。有关详细信息,请阅读。如果您的架构未更改,请尝试以下操作:
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);
});
});
});
});
});
如果您的架构未更改,请尝试以下操作:
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);
});
});
});
});
});
为了按字段对记录进行分组,请尝试在聚合中使用中的$group。这对我很有效 示例
db.categories.aggregate(
[
{ $group : { _id : {category_name:"$category_name"}, categories: { $push: {category_name:"$category_name",_id:"$_id"} } } }
]
)
参考:
希望这能起作用。为了按字段分组记录,请尝试在聚合中使用$group。这对我很有效 示例
db.categories.aggregate(
[
{ $group : { _id : {category_name:"$category_name"}, categories: { $push: {category_name:"$category_name",_id:"$_id"} } } }
]
)
参考:
希望这能起作用。如果您想在不更改模式的情况下找到预期结果,那么基本上需要遵循一些复杂的mongo
聚合查询。要查找输出,我需要遵循以下步骤:
首先在$project
中检查parent\u category
等于null
如果为true,则添加\u id
否则添加parent\u category
现在,文档结构看起来像是以新的键名作为父项id
显示并按父项id
分组,并推送剩余数据,如类别名和父项类别
然后使用和区分父数据和子数据
在finally中,仅展开
单个数组对象,因此此单个数组对象和项目仅用于显示要显示的字段
检查工作聚合查询,如下所示:
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()
如果您想在不改变模式的情况下找到预期结果,那么基本上需要遵循一些复杂的mongo聚合
查询
首先在$project
中检查parent\u category
等于null
如果为true,则添加\u id
否则添加parent\u category
现在,文档结构看起来像是以新的键名作为父项id
显示并按父项id
分组,并推送剩余数据,如类别名和父项类别
然后使用和区分父数据和子数据
在finally中,仅展开
单个数组对象,因此此单个数组对象和项目仅用于显示要显示的字段
检查工作聚合查询,如下所示:
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()
你为什么一开始就这样设计你的文档?也许你可以重新设计你的mongoose schemma,并制作一些方法来验证父id以分配子类别它只是两个级别的类别?你的子类别可以有自己的子类别吗?@JoseOsorio我真的不明白你在说什么mean@yarons是的,只要两分钟级别、类别和子类别查看mongoose的此类别树库:。这里是作者的一篇博文:为什么您一开始就这样设计文档?也许您可以重新设计mongoose架构,并制定一些方法来验证父级id以分配子类别。它只分配两个级别的类别?您的子类别可以吗类别有自己的子类别吗?@JoseOsorio我真的不明白你在说什么mean@yarons是的,它将是两个级别,类别和子类别看看这个mongoose的类别树库:。这里是作者的一篇博文:为了满足我的需要,我不得不对它稍作修改,但总的来说,这正是我所需要的。谢谢!我不得不修改它一点有点适合我的需要,但总的来说这是我需要的。谢谢!