我的Node.js应用程序中具有以下架构:
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 }
}]
});
并且我正在尝试查询Vendors集合以返回以下结果:
{
_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"
}
}],
avgRating: 4
},
{
_id: "3132139i31ds9daskd",
vendorID: "dsi9dsik129dkdsdsds",
name: "XYZ",
customerReviews [{
stars: "2",
review: "bad",
customerData: {
_id: "zds91i23212019329",
name: "Michael Smith"
}
},
{
stars: "5",
review: "Perfect",
customerData: {
_id: "ldso91232131ds9911",
name: "Mary"
}
}],
avgRating: 3.5
} ],
name: "Vendor XYZ"
}
基于此处的较早答案,我在对其进行一些修改以包含平均评分之后使用了以下汇总查询,但不幸的是,它将始终仅从供应商数据产品数组中返回一种产品,并且会合并该产品中所有产品的评论单个产品退回,所以我想知道是否有人可以提供帮助并告诉我在这里我可能会缺少什么/做错了什么?
{"$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"
}
}
}},
{ $addFields: { avgRating: { $avg: '$customerReviews.stars' } } }
],
"as":"productsData"
}}
样本数据:
Category:
{
"_id" : ObjectId("5de7fc530ce9d05be4024170"),
"categoryName" : "Glass",
"__v" : 0
}
User:
{
"_id" : ObjectId("5d6671ae7be3be4e18ebe9bb"),
"firstName" : "Mark",
"lastName" : "Smith",
"__v" : 0
}
Customer:
{
"_id" : ObjectId("5dd7cb11f4b2544253368f24"),
"customerName" : "Michael White",
"__v" : 0
},
{
"_id" : ObjectId("5dd7cb11f4b2544253372e33"),
"customerName" : "Mary",
"__v" : 0
}
Vendor:
{
"_id" : ObjectId("5de7fc6a0ce9d05be4024171"),
"category" : [
ObjectId("5de7fc530ce9d05be4024170")
],
"products" : [
ObjectId("5de8474ccd0bbc05256db819"), ObjectId("5de8474ccd0bbc05255eq323")
],
"userID" : ObjectId("5d6671ae7be3be4e18ebe9bb"),
"vendorName" : "Michael White",
"__v" : 0
}
Product:
{
"_id" : ObjectId("5de8474ccd0bbc05256db819"),
"vendorID" : ObjectId("5de7fc6a0ce9d05be4024171"),
"name" : "Red Sause",
"customerReviews" : [
{
"moderated" : false,
"_id" : ObjectId("5de7fcf20ce9d05be4024175"),
"customerId" : ObjectId("5dd7cb11f4b2544253368f24"),
"stars" : 3,
"review" : "Didn't like it that much :( ",
"date" : ISODate("2019-12-04T18:37:38.253Z")
}
],
"__v" : 0
},
{
"_id" : ObjectId("5de8474ccd0bbc05255eq323"),
"vendorID" : ObjectId("5de7fc6a0ce9d05be4024171"),
"name" : "Cups",
"customerReviews" : [
{
"moderated" : false,
"_id" : ObjectId("5de7fcf20ce9d05be4021111"),
"customerId" : ObjectId("5dd7cb11f4b2544253368f24"),
"stars" : 5,
"review" : "Excellent ",
"date" : ISODate("2019-12-04T18:37:38.253Z")
},
{
"moderated" : true,
"_id" : ObjectId("5de7fcf20ce9d05be4022222"),
"customerId" : ObjectId("5dd7cb11f4b2544253372e33"),
"stars" : 4,
"review" : "Good ",
"date" : ISODate("2019-12-04T18:37:38.253Z")
}
],
"__v" : 0
}