Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mongodb 使用$lookup聚合相关属性上的组_Mongodb_Mongoose_Mongodb Query_Aggregation Framework - Fatal编程技术网

Mongodb 使用$lookup聚合相关属性上的组

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

我正在尝试执行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: 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")
这意味着该集合由其正确的名称引用。但一般来说,大多数人不会这样做,所以区分是很重要的