1

I'm trying the MongoDB aggregation framework to work with nested documents but having trouble returning the expected output, specifically in the $graphLookup stage. In a non-nested schema, it correctly looks up all the documents as defined in the options and returns all. But in a nested one, it only returns one. I have tried $unwind and $replaceRoot as answered here but now it does not work. It would be more understandable through code so here are the samples.

Non-nested document (fileSystem does not count)

db={
  "fileSystem": [
    {
      "_id": "a",
      "label": "Root",
      "children": [
        "b",
      ],
    },
    {
      "_id": "b",
      "label": "Nested folder 1",
      "children": [
        "c",
        "d",
        "e"
      ],
      "parent": "a"
    },
    {
      "_id": "c",
      "label": "Nested File 1.1",
      "parent": "b"
    },
    {
      "_id": "d",
      "label": "Nested File 1.2",
      "parent": "b"
    },

  ]
}

// Aggregation Query

db.fileSystem.aggregate([
  {
    "$match": {
      "_id": "a"
    }
  },
  {
    "$graphLookup": {
      "from": "fileSystem",
      "startWith": "$children",
      "connectFromField": "children",
      "connectToField": "_id",
      "as": "nest",
      "depthField": "level",
      "maxDepth": 1
    }
  },
])

// correct and expected result

[
  {
    "_id": "a",
    "children": [
      "b"
    ],
    "label": "Root",
    "nest": [
      {
        "_id": "b",
        "children": [
          "c",
          "d",
          "e"
        ],
        "label": "Nested folder 1",
        "level": NumberLong(0),
        "parent": "a"
      },
      {
        "_id": "d",
        "label": "Nested File 1.2",
        "level": NumberLong(1),
        "parent": "b"
      },
      {
        "_id": "c",
        "label": "Nested File 1.1",
        "level": NumberLong(1),
        "parent": "b"
      }
    ]
  }
]

Nested document and query

db={
  "fileSystem": [
    {
      pp: [
        {
          "_id": "a",
          "label": "Root",
          "children": [
            "b",
          ],
        },
        // ... same as previous
      ]
    }
  ]
}

// Aggregation Query

db.fileSystem.aggregate([
  {
    "$unwind": "$pp"
  },
  {
    "$replaceRoot": {
      "newRoot": "$pp"
    }
  },
  {
    "$match": {
      "_id": "a"
    }
  },
  {
    "$graphLookup": {
      "from": "fileSystem",
      "startWith": "$pp.children",
      "connectFromField": "pp.children",
      "connectToField": "pp._id",
      "as": "nest",
      "depthField": "level",

    }
  }, 
])

// incorrect result

[
  {
    "_id": "a",
    "children": [
      "b"
    ],
    "label": "Root",
    "nest": []
  }
]

Expected: https://mongoplayground.net/p/A4yDGUHka58

Bugged: https://mongoplayground.net/p/ZlQyDBrYSZr

Nugget
  • 81
  • 1
  • 6
  • 23
  • Can you please [edit] to pose a clear, precise question? Maybe your question can be inferred, but this is a **question** and answer site. You can see [ask] for guidance. – starball Dec 31 '22 at 06:31

1 Answers1

1

$graphLookup searches the collection given in from for matching documents. It uses each document in the pipeline as a starting point, but it does not search for, and will not return documents from the pipline.

In the sample data there is there is only 1 document, so the best you'll get in that case is for the next array to contain the original document.

Playground

Joe
  • 25,000
  • 3
  • 22
  • 44
  • I see. Then the solution is to put the array directly after. But then that is not possible in my case since the `fileSystem` is nested. Actually my purpose with the `$graphLookup` is to do [this](https://mongoplayground.net/p/sCRRUCzTHBA) but nested. Can you help me with this? – Nugget Dec 31 '22 at 11:13