首页 > 解决方案 > 使用管道中的数组中的对象值执行 $lookup

问题描述

所以我有 3 个模型user,propertytestimonials.

推荐书有propertyId, message& userId。我已经能够通过管道获得每个属性的所有推荐。

Property.aggregate([
  { $match: { _id: ObjectId(propertyId) } },
  {
      $lookup: {
        from: 'propertytestimonials',
        let: { propPropertyId: '$_id' },
        pipeline: [
          {
            $match: {
              $expr: {
                $and: [{ $eq: ['$propertyId', '$$propPropertyId'] }],
              },
            },
          },
        ],
        as: 'testimonials',
      },
    },
]) 

返回的属性如下所示

{
 .... other property info,
 testimonials: [
  {
    _id: '6124bbd2f8eacfa2ca662f35',
    userId: '6124bbd2f8eacfa2ca662f29',
    message: 'Amazing property',
    propertyId: '6124bbd2f8eacfa2ca662f2f',
  },
  {
    _id: '6124bbd2f8eacfa2ca662f35',
    userId: '6124bbd2f8eacfa2ca662f34',
    message: 'Worth the price',
    propertyId: '6124bbd2f8eacfa2ca662f2f',
  },
 ]
}

用户架构

firstName: {
  type: String,
  required: true,
},
lastName: {
  type: String,
  required: true,
},
email: {
  type: String,
  required: true,
},

属性架构

name: {
  type: String,
  required: true,
},
price: {
  type: Number,
  required: true,
},
location: {
  type: String,
  required: true,
},

见证架构

propertyId: {
  type: ObjectId,
  required: true,
},
userId: {
  type: ObjectId,
  required: true,
},
testimonial: {
  type: String,
  required: true,
},

现在的问题是我如何$lookupuserId每个推荐中显示用户的信息,而不仅仅是每个推荐中的 id?

我希望我的回复结构如下

{
    _id: '6124bbd2f8eacfa2ca662f34',
    name: 'Maisonette',
    price: 100000,
    testimonials: [
        {
            _id: '6124bbd2f8eacfa2ca662f35',
            userId: '6124bbd2f8eacfa2ca662f29',
            testimonial: 'Amazing property',
            propertyId: '6124bbd2f8eacfa2ca662f34',
            user: {
                _id: '6124bbd2f8eacfa2ca662f29',
                firstName: 'John',
                lastName: 'Doe',
                email: 'jd@mail.com',
            }
        },
        {
            _id: '6124bbd2f8eacfa2ca662f35',
            userId: '6124bbd2f8eacfa2ca662f27',
            testimonial: 'Worth the price',
            propertyId: '6124bbd2f8eacfa2ca662f34',
            user: {
                _id: '6124bbd2f8eacfa2ca662f27',
                firstName: 'Sam',
                lastName: 'Ben',
                email: 'sb@mail.com',
            }
        }
    ]
}

标签: node.jsmongodbmongooseaggregation-frameworklookup

解决方案


您可以将$lookup舞台放在管道内,

  • $lookup与用户集合
  • $addFields,$arrayElemAt从上面的用户查找结果中获取第一个元素
Property.aggregate([
  { $match: { _id: ObjectId(propertyId) } },
  {
    $lookup: {
      from: "propertytestimonials",
      let: { propPropertyId: "$_id" },
      pipeline: [
        {
          $match: {
            $expr: { $eq: ["$propertyId", "$$propPropertyId"] }
          }
        },
        {
          $lookup: {
            from: "users",
            localField: "userId",
            foreignField: "_id",
            as: "user"
          }
        },
        {
          $addFields: {
            user: { $arrayElemAt: ["$user", 0] }
          }
        }
      ],
      as: "testimonials"
    }
  }
])

操场


推荐阅读