【问题标题】:mongoose recursive nesting猫鼬递归嵌套
【发布时间】:2020-06-04 04:26:51
【问题描述】:

在我的项目中,用户可以创建产品。每个用户都有对其所有产品的引用,每个产品都有对其用户的引用。

用户和产品都有一个“名称”字段。

我需要获取所有用户产品数组,并且在该数组中我想要产品名称和 创建它的用户名(只有那些字段,没有其他字段)。

例如:

用户:

{ _id: 1, name: 'josh', productIds: [1,3]}
{ _id: 2, name: 'sheldon', productIds: [2]}

产品:

{ _id: 1, name: 'table', price: 45, userId: 1}
{ _id: 2, name: 'television', price: 25 userId: 2}
{ _id: 3, name: 'chair', price: 14 userId: 1}

我想得到以下结果:

{ _id: 1, name: 'josh', 
    products: {
        { _id: 1, name: 'table', user: { _id: 1, name: 'josh' },
        { _id: 3, name: 'chair', user: { _id: 1, name: 'josh' },
    }
}
{ _id: 2, name: 'sheldon', 
    products: {
        { _id: 2, name: 'television', userId: { _id: 2, name: 'sheldon' }
    }
}

我尝试了以下未填充内部 userId 的查询,只留下了 id(无名称):

User.aggregate([
  { 
    $lookup: 
      { 
        from: 'products',
        localField: 'productIds',
        foreignField: '_id',
        as: 'products' 
      }  
  }

我还尝试了以下方法,它与第一个查询相同,只是它只为每个用户重试了第一个产品:

User.aggregate([
  { 
    $lookup: 
      { 
        from: 'products',
        localField: 'productIds',
        foreignField: '_id',
        as: 'products' 
      }  
  },
  {
    $unwind: {
      path: "$products",
      preserveNullAndEmptyArrays: true
    }
  },
  {
    $lookup: {
      from: "user",
      localField: "products.userId",
      foreignField: "_id",
      as: "prodUsr",
    }
  },
  {
    $group: {
      _id : "$_id",
      products: { $push: "$products" },
      "doc": { "$first": "$$ROOT" }
    }
  },
  {
    "$replaceRoot": {
    "newRoot": "$doc"
    }
}

产品:

const schema = new Schema(
  {
    name: {
      type: String,
      required: true
    },
    price: {
      type: Number,
      required: true
    },
    userId: {
      type: Schema.Types.ObjectId, 
      ref: 'User',
      required: true
    },
  }
);

module.exports = mongoose.model('Product', schema);

用户:

const schema = new Schema(
  {
    name: {
      type: String,
      required: true,
      unique: true
    },
    productIds: [{
      type: Schema.Types.ObjectId, 
      ref: 'Product',
      require: false
    }],
  { timestamps: true }
);

module.exports = mongoose.model('User', schema);

我们将不胜感激任何帮助

【问题讨论】:

    标签: mongodb mongoose aggregation-framework aggregate lookup


    【解决方案1】:

    对于$lookup with custom pipeline 和另一个嵌套的$lookup,这看起来是一个完美的场景。内层允许你处理product-> user 关系,而外层处理user -> product 一个:

    db.Users.aggregate([
        {
            $project: {
                productIds: 0
            }
        },
        {
            $lookup: {
                from: "Products",
                let: { user_id: "$_id" },
                pipeline: [
                    {
                        $match: {
                            $expr: {
                                $eq: [ "$userId", "$$user_id" ]
                            }
                        }
                    },
                    {
                        $lookup: {
                            from: "Users",
                            localField: "userId",
                            foreignField: "_id",
                            as: "user"
                        }
                    },
                    {
                        $unwind: "$user"
                    },
                    {
                        $project: {
                            "user.productIds": 0,
                            "price": 0,
                            "userId": 0
                        }
                    }
                ],
                as: "products"
            }
        }
    ])
    

    Mongo Playground

    【讨论】:

      猜你喜欢
      • 2018-06-11
      • 2021-03-23
      • 2019-03-22
      • 2018-06-23
      • 1970-01-01
      • 1970-01-01
      • 2018-10-30
      • 2014-03-27
      相关资源
      最近更新 更多