首页 > 解决方案 > Mongodb $graphLookup 聚合不一致的输出顺序和排序

问题描述

我有这个聚合操作,它给了我正确的输出,但顺序不一致。当我重新加载时,嵌套的输出数组(posteriorThread)改变了文档的顺序,似乎没有韵或原因!

我很困惑为什么订单会不断变化,我想知道为什么会发生这种情况,但我想我会对其进行排序,我这样做了,但我无法将它重新组合在一起。

我将在下面向您展示我的两个损坏的解决方案,但本质上我想要输出 1,但顺序正确。我正在使用猫鼬,但这不应该有所作为。

谢谢。

1:订单不一致解决方案

const posteriorThread = await Comment.aggregate([
      {
        $match: {
          _id: post.threadDescendant,
        },
      },
      {
        $graphLookup: {
          from: 'comments',
          startWith:'$threadDescendant',
          connectFromField: 'threadDescendant',
          connectToField: '_id',
          as: 'posteriorThread',
        },
      },
    ]);

输出:1


posteriorThread [
  {
    "_id": "000",
    "name": "foo bar",
    "text": "testing one",
    "threadDescendant": "123",
    "posteriorThread": [
      {
        "_id": "234",
        "name": "foo bar",
        "text": "testing four",
        "threadDescendant": "345"
      },
      {
        "_id": "345",
        "name": "foo bar",
        "text": "testing three",
      }, 
      {
        "_id": "123",
        "name": "foo bar",
        "text": "testing two",
        "threadDescendant": "234"
      },  
    ]
  }
]

2:更正旧但丢失根文件

    const posteriorThread = await Comment.aggregate([
      {
        $match: {
          _id: post.threadDescendant,
        },
      },
      {
        $graphLookup: {
          from: 'comments',
          startWith: '$threadDescendant',
          connectFromField: 'threadDescendant',
          connectToField: '_id',
          as: 'posteriorThread',
        },
      },
      {
        $unwind: '$posteriorThread',
      },
      {
        $sort: { 'posteriorThread.depth': 1 },
      },
      {
        $group: { _id: '$_id', posteriorThread: { $push: '$posteriorThread' } },
      },
    ]);

输出 2:

posteriorThread [
  {
    "_id": "000",
    "posteriorThread": [
      {
        "_id": "123",
        "name": "foo bar",
        "text": "testing two",
        "threadDescendant": "234"
      },  
      {
        "_id": "234",
        "name": "foo bar",
        "text": "testing four",
        "threadDescendant": "345"
      },
      {
        "_id": "345",
        "name": "foo bar",
        "text": "testing three",
      }, 
    ]
  }
]

标签: javascriptnode.jsjsonmongodbmongoose

解决方案


$graphLookup管道阶段不提供任何内置排序功能,因此您的第二种方法是正确的。您只需要使用$first来保留根对象的字段。您可以使用$replaceRoot和特殊$$ROOT变量来避免明确指定每个字段:

{
    $group: {
        _id: "$_id",
        posteriorThread: { $push: "$posteriorThread" },
        root: { $first: "$$ROOT" }
    }
},
{
    $project: {
        "root.posteriorThread": 0
    }
},
{
    $replaceRoot: {
        newRoot: {
            $mergeObjects: [
                { posteriorThread: "$posteriorThread" },
                "$root"
            ]
        }
    }
}

蒙戈游乐场


推荐阅读