简体   繁体   English

如何在 mongoose 的子文档数组中查找字段?

[英]How to lookup a field in an array of subdocuments in mongoose?

I have an array of review objects like this:我有一系列这样的评论对象:

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

What I want to achieve is to lookup the author field and get the user data, but the problem is that the lookup I am trying to use only returns this to me:我想要实现的是查找作者字段并获取用户数据,但问题是我尝试使用的查找只返回给我:

Code:代码:

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

Response:回复:

api的响应

Any way to get the author's data in that field?有什么方法可以获取作者在该领域的数据? That's where the author's Id is.这就是作者的身份。

Try to execute below query on your database:尝试在您的数据库上执行以下查询:

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" },
    },
  },
]);

Test: MongoDB-Playground测试: MongoDB-Playground

Note: Just in case if you've other fields in document along with reviews that needs to be preserved in output then starting at $group use these stages:注意:以防万一您在文档中有其他字段以及需要保留在 output 中的reviews ,然后从$group开始使用这些阶段:

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

Test: MongoDB-Playground测试: MongoDB-Playground

Note: Try to keep queries to run on lesser datasets maybe by adding $match as first stage to filter documents & also have proper indexes.注意:尝试保持查询在较小的数据集上运行,可能通过添加$match作为第一阶段来过滤文档并具有适当的索引。

you should use populate('author') method of mongoose on the request to the server which gets the id of that author and adds the user data to the response of mongoose and dont forget to set your schema in a way that these two collections are connected in your review schema you should add ref to the schema which the author user is saved author: { type: Schema.Types.ObjectId, ref: 'users' },您应该在对服务器的请求中使用 mongoose populate('author')方法,该服务器获取该作者的 id 并将用户数据添加到 mongoose 的响应中,并且不要忘记以这两个 Z0B9ABFE67CC31FCF16Z 的方式设置您的架构在您的评论架构中连接,您应该将 ref 添加到作者用户保存的架构作者:{ type: Schema.Types.ObjectId, ref: 'users' },

You can follow this code您可以按照此代码

$lookup:{
            from:'users',
            localField:'reviews.author',
            foreignField:'_id',
            as:'reviews.author'
        }
**OR**

> When You find the doc then use populate
> reviews.find().populate("author")


声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM