Mongodb 使用聚合框架返回自定义结果
我在Node.js应用程序中有以下模式:Mongodb 使用聚合框架返回自定义结果,mongodb,aggregation-framework,Mongodb,Aggregation Framework,我在Node.js应用程序中有以下模式: let CategorySchema = mongoose.Schema({ name: { type: String, required: true } }); let UserSchema = mongoose.Schema({ firstName: { type: String, required: true }, lastName: { type: String, required: tr
let CategorySchema = mongoose.Schema({
name: { type: String, required: true }
});
let UserSchema = mongoose.Schema({
firstName: { type: String, required: true },
lastName: { type: String, required: true }
});
let CustomerSchema = mongoose.Schema({
name: { type: String, required: true }
});
let VendorSchema = mongoose.Schema({
userID: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
category: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Category' }],
products: [ { type: mongoose.Schema.Types.ObjectId, ref: 'Product' } ],
name: { type: String, required: true }
});
let ProductSchema = mongoose.Schema({
vendorID: { type: mongoose.Schema.Types.ObjectId, ref: 'Vendor' },
name: { type: String, index: true, required: true },
customerReviews: [{
stars: { type: Number, required: false },
review: { type: String, required: false },
customerId: { type: mongoose.Schema.Types.ObjectId, ref: 'Customer', required: true }
}]
});
我正在尝试查询供应商集合以返回以下结果:
{
_id: "dsi9dsik129dkdsdsds",
userData: {
_id: "dsa9dskd2kwd29dkkss",
firstName: "Michael",
lastName: "White"
},
categoryData: {
_id: "e9dids91i239dskds91",
name: "Category A"
},
productsData: [ {
_id: "3132139i31j32131",
vendorID: "dsi9dsik129dkdsdsds",
name: "Product ABC",
customerReviews [{
stars: "5",
review: "Good",
customerData: {
_id: "zds91i232131j2321j",
name: "John silver"
}
},
{
stars: "3",
review: "Bad",
customerData: {
_id: "ldso91232131j2321j",
name: "Mark Spenser"
}
}]
} ],
name: "Vendor XYZ"
}
我已经在供应商集合(意思是Vendors.aggregate(…)上构建了以下查询,但我不确定如何格式化返回的结果以及如何在Customers review中检索客户数据,因此我想知道是否有人可以帮我?谢谢
(
{ $lookup: { from: "users", localField: "userID", foreignField: "_id", as: "userData" } },
{ $lookup: { from: "categories", localField: "category", foreignField: "_id", as: "categoryData" } },
{ $lookup: { from: "products", localField: "products", foreignField: "_id", as: "productsData" } },
{ $group: { _id: null, content: { $push: '$$ROOT' },count: { $sum: 1 } } },
{ $project: { content: { $slice: [ '$content', 0, 10 ] }, count: 1, _id: 0 } },
)
测试:
注意:在上面的测试中,我在名称之前添加了实体名称,例如vendorName/customerName,只是为了避免在多个集合中的字段“名称”之间产生混淆您可以在3.6版本的聚合下面进行尝试
{"$lookup":{
"from": "users",
"localField": "userID",
"foreignField": "_id",
"as": "userData"
}},
{"$unwind":"$userData"},
{"$lookup":{
"from": "categories",
"localField": "category",
"foreignField": "_id",
"as": "categoryData"
}},
{"$lookup":{
"from":"products",
"let":{"products":"$products"},
"pipeline":[
{"$match":{"$expr":{"$in":["$_id","$$products"]}}},
{"$unwind":{"path":"$customerReviews", "preserveNullAndEmptyArrays":true}},
{"$lookup":{
"from":"customers",
"localField":"customerReviews.customerId",
"foreignField":"_id",
"as":"customerData"
}},
{"$unwind":{"path":"$customerData", "preserveNullAndEmptyArrays":true}},
{"$group":{
"_id":"$_id",
"vendorID": {"$first":"$vendorID"},
"name": {"$first":"$name"},
"customerReviews":{
"$push":{
"stars": "$customerReviews.stars",
"review": "$customerReviews.review",
"customerData":"$customerData"
}
}
}}
],
"as":"productsData"
}}
您能添加一些测试吗?谢谢您的努力,categoryData和userData返回得很好,但是产品总是返回空的,所以我想知道我是否遗漏了什么?谢谢SNP。没有测试数据我什么也说不出来。你能更新帖子以包含你的测试数据吗?我已经编辑了问题,添加了一些测试数据。我还为“name”字段添加了前缀entity name,以避免不同集合中名称字段之间的混淆。再次感谢您的时间和努力。刚刚核实。我可以看到您发布的样本数据的产品数据。可能是您没有对某些产品的客户评论。您可以尝试
“preserveNullAndEmptyArrays”:true
选项以在行为空或缺失时保留行。更新答案。。另外,请验证查询中的集合名称是否正确。
{"$lookup":{
"from": "users",
"localField": "userID",
"foreignField": "_id",
"as": "userData"
}},
{"$unwind":"$userData"},
{"$lookup":{
"from": "categories",
"localField": "category",
"foreignField": "_id",
"as": "categoryData"
}},
{"$lookup":{
"from":"products",
"let":{"products":"$products"},
"pipeline":[
{"$match":{"$expr":{"$in":["$_id","$$products"]}}},
{"$unwind":{"path":"$customerReviews", "preserveNullAndEmptyArrays":true}},
{"$lookup":{
"from":"customers",
"localField":"customerReviews.customerId",
"foreignField":"_id",
"as":"customerData"
}},
{"$unwind":{"path":"$customerData", "preserveNullAndEmptyArrays":true}},
{"$group":{
"_id":"$_id",
"vendorID": {"$first":"$vendorID"},
"name": {"$first":"$name"},
"customerReviews":{
"$push":{
"stars": "$customerReviews.stars",
"review": "$customerReviews.review",
"customerData":"$customerData"
}
}
}}
],
"as":"productsData"
}}