【问题标题】:Mongodb $graphLookup aggregation inconsistent ouput order and sortingMongodb $graphLookup 聚合不一致的输出顺序和排序
【发布时间】:2020-11-18 20:04:32
【问题描述】:

我有这个聚合操作,它给了我正确的输出,但顺序不一致。重载时,嵌套的输出数组(postteriorThread)改变了文档的顺序,好像没韵没道理!

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

我将在下面向您展示我的两个损坏的解决方案,但本质上我想要输出 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",
      }, 
    ]
  }
]

【问题讨论】:

    标签: javascript node.js json mongodb mongoose


    【解决方案1】:

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

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

    Mongo Playground

    【讨论】:

    • 我为这个问题简化了它,但我还有更多的领域。无论如何要保留根文档中的所有字段而不手动添加每个字段?
    • @7iiBob 当然,看我修改后的答案
    • 我知道我需要使用root!我用root尝试过一些东西,但我无法弄清楚。非常感谢。这正是我所需要的。
    猜你喜欢
    • 2017-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-13
    • 2015-03-29
    • 1970-01-01
    • 1970-01-01
    • 2015-12-28
    相关资源
    最近更新 更多