MongoDB 聚合:将数组属性展平为根数组

ram*_*ram 3 javascript aggregate mongoose mongodb

我正在开发一个使用 递归查找评论线程的功能$graphLookUp,我几乎已经拥有它了。(虽然方式有点复杂,但它正在起作用!)

我需要的最后一步如下: 不要将嵌套posteriorThread作为根数组()的属性$$ROOT,而是将其合并到根本身。

  • 聚合代码:
const posteriorThread = await Comment.aggregate([
  {
    $match: {
      _id: post.threadDescendant
    }
  },

  {
    $graphLookup: {
      from: 'baseposts',
      startWith: '$threadDescendant',
      connectFromField: 'threadDescendant',
      connectToField: '_id',
      as: 'posteriorThread'
    }
  },

  {
    $unwind: '$posteriorThread'
  },

  {
    $sort: { 'posteriorThread.depth': 1 }
  },

  {
    $group: {
      _id: '$_id',
      posteriorThread: { $push: '$posteriorThread' },
      root: { $first: '$$ROOT' }
    }
  },

  {
    $project: {
      'root.posteriorThread': 0
    }
  },

  {
    $replaceRoot: {
      newRoot: {
        $mergeObjects: [
          {
            posteriorThread: '$posteriorThread'
          },
          '$root'
        ]
      }
    }
  }
]);
Run Code Online (Sandbox Code Playgroud)
  • 电流输出
 OUTPUT: posteriorThread
[
  {
    _id: '5f7eab40575e6fc56ee07604',
    onModel: 'BasePost',
    depth: 1,
    user: '5f5da45245c07cc06e51b09f',
    text: 'thread 0',
    isThread: true,
    threadDescendant: '5f7eabad575e6fc56ee07607',
    posteriorThread: [
      {
        _id: '5f7eabad575e6fc56ee07607',
        onModel: 'Comment',
        depth: 2,
        user: '5f5da45245c07cc06e51b09f',
        text: 'thread 1',
        isThread: true,
        threadDescendant: '5f7eac82575e6fc56ee07609'
      },
      {
        _id: '5f7eac82575e6fc56ee07609',
        onModel: 'Comment',
        depth: 3,
        user: '5f5da45245c07cc06e51b09f',
        text: 'thread 2',
        isThread: true
      }
    ]
  }
];

Run Code Online (Sandbox Code Playgroud)
  • 期望的输出
OUTPUT: posteriorThread 
[
  {
    _id: '5f7eab40575e6fc56ee07604',
    onModel: 'BasePost',
    depth: 1,
    user: '5f5da45245c07cc06e51b09f',
    text: 'thread 0',
    isThread: true,
    threadDescendant: '5f7eabad575e6fc56ee07607'
  },
  {
    _id: '5f7eabad575e6fc56ee07607',
    onModel: 'Comment',
    depth: 2,
    user: '5f5da45245c07cc06e51b09f',
    text: 'thread 1',
    isThread: true,
    threadDescendant: '5f7eac82575e6fc56ee07609'
  },
  {
    _id: '5f7eac82575e6fc56ee07609',
    onModel: 'Comment',
    depth: 3,
    user: '5f5da45245c07cc06e51b09f',
    text: 'thread 2',
    isThread: true
  }
];
Run Code Online (Sandbox Code Playgroud)

我可以在常规 js 聚合之后完成此操作,但我更喜欢在聚合中完成这一切。需要替换的部分是位mergeObjects,并用其他东西或group聚合替换并采取不同的策略,但我不确定该放什么。另外,如果您有任何其他建议来使其更清洁,我会洗耳恭听。

提前致谢。

Sun*_*nta 6

这真的很有挑战性。至少对于我来说。确实非常有趣的案例。让我们尝试一下我的解决方案。希望它有效..

db.test.aggregate([

    // PREVIOSU STEPS YOU ALREADY DID

    {
        $group: {
            _id: "$_id",
            items: {$push: "$$ROOT"},
            subItems: {$first: "$posteriorThread"}
        }
    },
    {
        $project: {
            "items.posteriorThread": 0
        }
    },
    {
        $addFields: {
            allItems: {
                $concatArrays: ["$items", "$subItems"]
            }
        }
    },
    {
        $group: {
            _id: null,
            mergedItems: {$push: "$allItems"}
        }
    },
    {
        $unwind: "$mergedItems"
    },
    {
        $unwind: "$mergedItems"
    },
    {
        $replaceRoot: {
          newRoot: "$mergedItems"
        }
    }

])
Run Code Online (Sandbox Code Playgroud)

  • 哈哈..不不。不需要。请。我很高兴它确实有帮助!谢谢你的询问。老实说,我不知道该怎么做,这对我来说也是实验。问题陈述很有趣。所以我开始研究这个问题,我也从中得到了一些教训。 (2认同)