【问题标题】:How to lookup a field in an array of subdocuments in mongoose?如何在猫鼬的子文档数组中查找字段?
【发布时间】:2020-07-25 09:19:15
【问题描述】:

我有一个这样的评论对象数组:

   "reviews": {
        "author": "5e9167c5303a530023bcae42",
        "rate": 5,
        "spoiler": false,
        "content": "This is a comment This is a comment This is a comment.",
        "createdAt": "2020-04-12T16:08:34.966Z",
        "updatedAt": "2020-04-12T16:08:34.966Z"
    },

我想要实现的是查找 author 字段并获取用户数据,但问题是我尝试使用的查找只返回给我:

代码:

 .lookup({
    from: 'users',
    localField: 'reviews.author',
    foreignField: '_id',
    as: 'reviews.author',
  })

回应:

有什么方法可以获取作者在该字段中的数据?这就是作者的 ID。

【问题讨论】:

  • 来自您的评论 (stackoverflow.com/questions/61199439/…) -> 您在以下答案中发现遗漏了什么/您无法理解的内容是什么?我看到已删除的评论 说工作完美 并且未被接受 - 如果您能准确指出出了什么问题,我可以帮助其他人,请找到更好的答案并将其发布在这里我会从中学习以了解真正的问题失踪了..!!
  • @whoami 这里的问题更好,请查看。 stackoverflow.com/questions/61212927/…

标签: mongodb mongoose mongodb-query aggregation-framework mongoose-populate


【解决方案1】:

尝试在您的数据库上执行以下查询:

db.reviews.aggregate([
  /** unwind in general is not needed for `$lookup` for if you wanted to match lookup result with specific elem in array is needed */
  {
    $unwind: { path: "$reviews", preserveNullAndEmptyArrays: true },
  },
  {
    $lookup: {
      from: "users",
      localField: "reviews.author",
      foreignField: "_id",
      as: "author", // Pull lookup result into 'author' field
    },
  },
  /** Update 'reviews.author' field in 'reviews' object by checking if   'author' field got a match from 'users' collection.
   * If Yes - As lookup returns an array get first elem & assign(As there will be only one element returned -uniques),
   * If No - keep 'reviews.author' as is */
  {
    $addFields: {
      "reviews.author": {
        $cond: [
          { $ne: ["$author", []] },
          { $arrayElemAt: ["$author", 0] },
          "$reviews.author",
        ],
      },
    },
  },
  /** Group back the documents based on '_id' field & push back all individual 'reviews' objects to 'reviews' array */
  {
    $group: {
      _id: "$_id",
      reviews: { $push: "$reviews" },
    },
  },
]);

测试: MongoDB-Playground

注意:以防万一您在文档中有其他字段以及需要在输出中保留的 reviews,然后从 $group 开始使用这些阶段:

  {
    $group: {
      _id: "$_id",
      data: {
        $first: "$$ROOT"
      },
      reviews: {
        $push: "$reviews"
      }
    }
  },
  {
    $addFields: {
      "data.reviews": "$reviews"
    }
  },
  {
    $project: {
      "data.author": 0
    }
  },
  {
    $replaceRoot: {
      newRoot: "$data"
    }
  }

测试: MongoDB-Playground

注意:尝试通过添加$match 作为第一阶段来过滤文档并具有适当的索引,以使查询在较小的数据集上运行。

【讨论】:

    【解决方案2】:

    您可以关注此代码

    $lookup:{
                from:'users',
                localField:'reviews.author',
                foreignField:'_id',
                as:'reviews.author'
            }
    **OR**
    
    > When You find the doc then use populate
    > reviews.find().populate("author")
    
    
    

    【讨论】:

    • 我不能在查询聚合()中使用 .populate()。
    【解决方案3】:

    你应该使用猫鼬的populate('author')方法对服务器的请求获取该作者的ID并将用户数据添加到猫鼬的响应中 并且不要忘记以连接这两个集合的方式设置您的架构 在您的评论模式中,您应该将 ref 添加到保存作者用户的模式中 作者:{类型:Schema.Types.ObjectId,参考:'用户'},

    【讨论】:

    • 我不能使用 .populate() 方法,因为我使用的是 .aggregate()。并且模型中的引用是正确的,因为使用 populate() 它对我来说非常有效,但使用查找它却不行。
    猜你喜欢
    • 1970-01-01
    • 2019-07-17
    • 2022-12-10
    • 2021-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-24
    • 2020-07-10
    相关资源
    最近更新 更多