Mongodb 使用$lookup聚合相关属性上的组
我正在尝试执行Mongodb聚合,该聚合将允许我对位于查找对象中的项进行分组,并根据位于子文档中的项进行计数,例如: 客户:Mongodb 使用$lookup聚合相关属性上的组,mongodb,mongoose,mongodb-query,aggregation-framework,Mongodb,Mongoose,Mongodb Query,Aggregation Framework,我正在尝试执行Mongodb聚合,该聚合将允许我对位于查找对象中的项进行分组,并根据位于子文档中的项进行计数,例如: 客户: - first: {type: Schema.Types.String, minlength: 1, maxlength: 35, required: true}, - middle: {type: Schema.Types.String, minlength: 1, maxlength: 35, required: true}, - last: {type: Schem
- first: {type: Schema.Types.String, minlength: 1, maxlength: 35, required: true},
- middle: {type: Schema.Types.String, minlength: 1, maxlength: 35, required: true},
- last: {type: Schema.Types.String, minlength: 1, maxlength: 35, required: true},
- email_address: {type: Schema.Types.String, minlength: 7, maxlength: 255, required: true},
- city: {type: Schema.Types.String, minlength: 1, maxlength: 75, required: true},
- state: {type: Schema.Types.String, minlength: 1, maxlength: 75, required: true},
- zipcode: {type: Schema.Types.String, minlength: 1, maxlength: 75, required: true}
订单:
- customer: {type: Schema.Types.ObjectId, ref: 'Customer'},
- [OrderLineItem]
产品:
- name: {type: Schema.Types.String, minlength: 1, maxlength: 35, required: true},
- manufacturer: {type: Schema.Types.String, minlength: 5, maxlength: 35, required: true},
- cost: {type: Schema.Types.Number, required: true},
- current_inventory: {type: Schema.Types.Number, required: true}
订单行项目:
- product: {type: Schema.Types.ObjectId, ref: 'Product'},
- quantity: {type: Schema.Types.Number, required: true},
- total_cost: {type: Schema.Types.Number, required: true}
获取zipcode购买的产品总数:
this.order.aggregate([
{$lookup: {from: "Customer", localField: "customer", foreignField: "_id", as: "customerObj"}},
{$group : {_id : {zipCode: "$customerObj.zipcode", products: "not sure what goes here...."}, total: { $count: "not sure what goes here..." }}}
])
对于上面的例子,我想得到一份按邮政编码购买的产品总数的报告。当我试图构建我的聚合时,我不知道该如何为这个场景编码 在所有情况下,操作员都将返回匹配项的“数组”。由于客户之间的关系是1:1
,因此您可以通过
您的问题没有命名包含OrderLineItem
数组的schema属性,因此我假设下面的“order\u line”
更改为您实际使用的内容
Order.aggregate([
// lookup the customer detail
{ "$lookup": {
"from": "customers",
"localField": "customer",
"foreignField": "_id",
"as": "customer"
}},
// Group by zip
{ "$group": {
"_id": { "$arrayElemAt": [ "$customer.zipcode", 0 ] },
"total_qty": { "$sum": "$order_lines.quantity" }
}}
])
如果您想从“产品”
细节本身中获得一些东西,如“制造商”
,并且需要将其作为一部分使用,那么就有必要进行另一项操作,并且该细节再次以相同的1:1
关系排列在一个数组中。但您需要先查看“订单行”
:
Order.aggregate([
// lookup the customer detail
{ "$lookup": {
"from": "customers",
"localField": "customer",
"foreignField": "_id",
"as": "customer"
}},
// $unwind the order lines
{ "$unwind": "$order_lines" },
// lookup the product detail
{ "$lookup": {
"from": "products",
"localField": "order_lines.product",
"foreignField": "_id",
"as": "order_lines.product"
}},
// Group by zip by manufacturer
{ "$group": {
"_id": {
"zip": { "$arrayElemAt": [ "$customer.zipcode", 0 ] },
"manufacturer": { "$arrayElemAt": [ "$order_lines.product.manufactuer", 0 ] }
},
"total_qty": { "$sum": "$order_lines.quantity" }
}}
])
您可能会注意到,尽管只有一种情况下在“order\u line”
数组上使用了该操作,但此处的用法没有改变。这是因为在MongoDB 3.2中,您可以直接对包含内部属性值的数组进行标记,因此:
"items": [{ "a": 1, "b": 2 }, { "a": 2, "b": 3 }]
当引用为“”$items时,“
变成:
[1,2]
此外,还更改了运算符,以便它也可以接受项目的“数组”以及在
注意集合上使用的命名约定。默认情况下,Mongoose使用一种约定,即给定的单数型号名称,即
“Customer”
将被“复数化”为“products”
,作为实际的集合名称。$lookup
操作符在服务器上运行,而不是在了解模型的客户端代码中运行,因此服务器只知道集合
您可能故意命名了要在mongoose模型声明中使用的集合,如:
mongoose.model("Customer", customerSchema, "customer")
这意味着该集合由其正确的名称引用。但一般来说,大多数人不会这样做,所以区分是很重要的