如何在ObjectIs数组中使用外键时在两个集合之间进行连接

时间:2018-02-14 21:57:05

标签: mongodb mongoose aggregation-framework

假设我有以下mongodb的收集结构:

  • 用户

    • ID
    • 用户id
    • EMAILADDRESS
  • 产品

    • ID
    • SKU
  • productRewards

    • 产品:[{productId}],
    • pointsNeeded
    • REWARDAMOUNT
  • productUsers

    • 的productId
    • 用户id

下面列出了猫鼬模式:

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}
}

ProductSchema: Schema = new Schema({
    sku: {type: Schema.Types.String, minlength: 1, maxlength: 30, required: true},
    price: {type: Schema.Types.Number, required: true}
}

ProductRewardSchema: Schema = new Schema({
    products: [{productId: {type: Schema.Types.ObjectId, required: true, ref: 'product'}}],
    pointsNeeded: {type: Schema.Types.Number, required: true},
    rewardAmount: {type: Schema.Types.Number, required: true}
}

ProductUserSchema: Schema = new Schema({
    productId: {type: Schema.Types.ObjectId, ref: 'product'},
    userId: {type: Schema.Types.ObjectId, ref: 'user'}
}

数据库版本:3.6

我需要计算用户积累的积分,以确定他们有资格获得的奖励。我应该如何在mongodb中执行此操作?我知道如何在sql中完成这项工作而不是nosql。

我正在尝试这样的事情,但我不确定这是对的:

db.productUsers.aggregate(
    { "$unwind": "productRewards.products" },
    {
        "$lookup": {
            from: "productRewards",
            localField: "productRewards.products.productId",
            foreignField: "productId",
            as: "rewards"
        }
    },
    {
        "$group": {
            userId: "$userId", productId: "$productId", total:  { $sum: "$price" }
        }
    },
    {
        "$project": {
            userId: 1,
            productId: 1,
            total: 1
        }
    }
)

另外,我期待像这样的json输出:

{" userId":" ObjectId string"," name":"产品名称字符串","总计&#34 ;:50}

1 个答案:

答案 0 :(得分:0)

我将从productUsers集合开始,并在productId上加入productRewards集合并从那里开始工作。

这样的东西
db.productUsers.aggregate(
    {
        "$lookup": {
            from: "productRewards",
            localField: "productId",
            foreignField: "products.productId",
            as: "rewards"
        }
    },
    {
        "$project": {
            userId: 1,
            productId: 1,
            points: {$arrayElemAt:["$rewards.pointsNeeded", 0]}
        }
    }
)