对mongodb中的子子文档执行连接

时间:2018-02-15 23:44:58

标签: mongodb mongoose aggregation-framework

我正在尝试使用mongodb进行左连接,以计算每个用户在每个商店中购买的每个产品的数量。我是聚合和nosql的新手,并且在查看如何将users.products.stores加入stores表以获取商店的名称和products表的产品表到users.products.productId以获取其名称时遇到问题。产品。

我想打印出以下json:

{"userId": "user1", "StoreName": "Store 1", "ProductName": "Crest Toothpaste", "# of Purchases": 200}

我正在使用mongodb的3.6版本

  • 存储
    • ID
    • 名称
    • 城市
    • 状态
    • 邮政编码
  • 用户
    • ID
    • 用户id
    • EMAILADDRESS
    • 产品:[{productId,stores:[{storeId}]}]
  • 产品
    • ID
    • SKU
    • productRewards:[{pointsNeeded,rewardAmount}]

以下是架构的示例:

UserSchema: Schema = new Schema({
        userName: {type: Schema.Types.String, minlength: 6, maxlength: 10, required: true},
        emailAddress: {type: Schema.Types.String, minlength: 8, maxlength: 55, required: true}
    products: [{productId: {type: Schema.Types.ObjectId, required: true, ref: 'product’},
              stores: [{storeId: {type: Schema.Types.ObjectId, required: true, ref: ‘store’}]]
})

ProductSchema: Schema = new Schema({
    name: {type: Schema.Types.String, minlength: 1, maxlength: 30, required: true},
    price: {type: Schema.Types.Number, required: true},
    productRewards: [{
        pointsNeeded: {type: Schema.Types.Number, required: true},
        rewardAmount: {type: Schema.Types.Number, required: true}
    }]
}

StoreSchema: Schema = new Schema({
        name: {type: Schema.Types.String, minlength: 10, maxlength: 30, required: true},
        city: {type: Schema.Types.String, minlength: 1, maxlength: 35, required: true},
    state: {type: Schema.Types.String, minlength: 1, maxlength: 35, required: true},
    zipCode: {type: Schema.Types.String, minlength: 5, maxlength: 13, required: true},

}

我尝试做类似这样的事情但是我没有把它仅仅拉到连接左侧和右侧的memberId字段相等的位置,而不是看起来更像是一个完整的连接:

db.user.aggregate(
    { $unwind : "$products" },
    { $unwind : "$products.stores" },
    { "$lookup": {
        from: "stores",
        localField: "storeId",
        foreignField: "_id",
        as: "stores"
    }
})

如果一个是子子文档,我怎么能执行必要的连接?我对每个连接看起来特别是子子文档的内容感到困惑。

1 个答案:

答案 0 :(得分:0)

您可以使用以下聚合。

以下查询为每个产品和商店信息执行多个$lookup,然后在商店,用户和产品上显示$group,以计算购买次数。

$unwind产品嵌入式数组后跟$lookup以获取产品信息。

$unwind产品内嵌商店嵌入式数组,然后$lookup获取商店信息。

db.users.aggregate([
  {"$unwind":"$products"},
  {"$lookup":{
    "from":"products",
    "localField":"products.productId",
    "foreignField":"_id",
    "as":"products.product"
  }},
  {"$unwind":"$products.stores"},
  {"$lookup":{
    "from":"stores",
    "localField":"products.stores.storeId",
    "foreignField":"_id",
    "as":"products.stores"
  }},
  {"$group":{
    "_id":{
      "userId":"$userId",
      "storeId":"$products.stores.storeId",
      "productId":"$products.productId"
    },
    "StoreName":{"$first":{"$arrayElemAt":["$products.stores.name", 0]}},
    "ProductName":{"$first":{"$arrayElemAt":["$products.product.name", 0]}},
    "# of Purchases":{"$sum":1}
  }},
  {"$project":{
    "_id":0,
    "userId":"$_id.userId",
    "StoreName":1,
    "ProductName":1,
    "# of Purchases":1
  }}
])
相关问题