Mongodb 使用聚合框架返回自定义结果

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

我在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 }
        }]
});
我正在尝试查询供应商集合以返回以下结果:

{
    _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"
}}