【问题标题】:Can't $unwind documents after $group在 $group 之后不能 $unwind 文档
【发布时间】:2021-06-28 23:02:25
【问题描述】:

我正在学习 Mongo,但我对聚合函数一无所知。我有一个可以发布许多不同类型帖子的用户,我通过 blogName 匹配用户,然后 $lookup 所有具有匹配用户 ID 的帖子。

在那之后,我被难住了。如果我放松并且不分组,那么我会得到一团糟的已加入文档,但我想要的只是帖子。

如果我在 $unwind 之后进行分组,那么文档将转回对象。

这段代码:

return User
          .aggregate([
            { 
              $match: { 
                blogName: blogName 
              } 
            },
            {
              $lookup: {
                from: 'posts',
                localField: '_id',
                foreignField: 'user',
                as: 'posts'
              }
            },
            {
              $unwind: "$posts"
            },
            {
              $group: {
                _id: "$_id",
                'posts': { $push: { fields: '$posts' } }
              }
            },

给我这个:

[
   {
     _id: 6065e579bf709d81274cc51e,
     posts: [ [Object], [Object], [Object], [Object] ]
   }
]

$group 之后添加第二个$unwind 只会给我这个:

[
   { _id: 6065e579bf709d81274cc51e, posts: { fields: [Object] } },
   { _id: 6065e579bf709d81274cc51e, posts: { fields: [Object] } },
   { _id: 6065e579bf709d81274cc51e, posts: { fields: [Object] } },
   { _id: 6065e579bf709d81274cc51e, posts: { fields: [Object] } }
]

这离我想要的更远。

我只想要帖子。如果我可以 $unwind 这个数组中的帖子,那么我可以从那里处理所有事情。我对此有什么不明白的地方?

更新 1:

如果我像这样使用 $project:

return User
          .aggregate([
            { 
              $match: { 
                blogName: blogName 
              } 
            },
            {
              $lookup: {
                from: 'posts',
                localField: '_id',
                foreignField: 'user',
                as: 'posts'
              }
            },
            {
              $unwind: "$posts"
            },
            {
              $project: {
                "_id": 0,
                "posts": "$posts"
              }
            },

我可以得到这个数组:

[
  {
    posts: {
       _id: 60664856447970128fee597b,
       descriptionImages: [],
       tags: [],
       likes: [],
       kind: 'TextPost',
       createdAt: 2021-04-01T22:25:26.531Z,
       updatedAt: 2021-04-01T22:25:26.531Z,
       title: '',
       body: '',
       user: 6065e579bf709d81274cc51e,
       __v: 0
    }
  },
  {
    posts: {
      _id: 60664925d2548912dc960e05,
      mainImages: [],
      descriptionImages: [],
      tags: [],
      likes: [],
      kind: 'PhotoPost',
      createdAt: 2021-04-01T22:28:53.179Z,
      updatedAt: 2021-04-01T22:28:53.179Z,
      user: 6065e579bf709d81274cc51e,
      description: '',
      __v: 0
    }
  },
  {
    posts: {
      _id: 6066495f347bb812fd6dc703,
      mainImages: [],
      descriptionImages: [],
      tags: [],
      likes: [],
      kind: 'PhotoPost',
      createdAt: 2021-04-01T22:29:51.815Z,
      updatedAt: 2021-04-01T22:29:51.815Z,
      user: 6065e579bf709d81274cc51e,
      description: '',
      __v: 0
    }
  },
  {
    posts: {
      _id: 60664961347bb812fd6dc704,
      descriptionImages: [],
      tags: [],
      likes: [],
      kind: 'TextPost',
      createdAt: 2021-04-01T22:29:53.385Z,
      updatedAt: 2021-04-01T22:29:53.385Z,
      title: '',
      body: '',
      user: 6065e579bf709d81274cc51e,
      __v: 0
    }
  }
]

但现在我对如何摆脱额外的嵌套感到困惑。我只需要每个帖子对象,而不需要在帖子下额外嵌套。

【问题讨论】:

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


【解决方案1】:

演示 - https://mongoplayground.net/p/bCwBJipyYYZ

db.collection.aggregate([
  { $match: { blogName: "abc" } },
  { $unwind: "$posts" },
  { $replaceRoot: { "newRoot": "$posts" } }
])

使用$replaceRoot

用指定的文档替换输入文档。该操作将替换输入文档中的所有现有字段,包括 _id 字段。您可以将现有的嵌入文档提升到顶层,或创建一个新文档进行提升(参见示例)。


User.aggregate([
    { $match: {  blogName: blogName } },
    { $lookup: { from: 'posts', localField: '_id', foreignField: 'user', as: 'posts' } },
    { $unwind: "$posts" },
    { $replaceRoot: { "newRoot": "$posts" } }
 ]

【讨论】:

    猜你喜欢
    • 2017-01-22
    • 2019-09-03
    • 2017-01-02
    • 2019-10-02
    • 1970-01-01
    • 1970-01-01
    • 2017-08-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多