uchiha itachi
uchiha itachi

Reputation: 195

How to add field in all nested documents in mongo

I have a document with a tree structure:

{
    "_id": "62e1f19f094a5696fd18f4e9",
    "parent": null,
    "children": [
          {
              "_id": "44e1f19f094a5696fd18f4o7",
              "parent": "62e1f19f094a5696fd18f4e9",
              "children": [
                    {
                        "_id": "62e1f19f094a5696fd18f4e9",
                        "parent": "44e1f19f094a5696fd18f4o7",
                        "children": []
                    }
               ] 
          }
    ] 
}

I want to add a new field "id" (without the underscore) which refers to "_id" to each document even if it is a child or parent I tried to do something like this:

$addFields: {id: $_id, children.id: $children._id} but in doesn't work

so, the final result I want to get

{
        "_id": "62e1f19f094a5696fd18f4e9",
        "id": "62e1f19f094a5696fd18f4e9",
        "parent": null,
        "children": [
              {
                  "_id": "44e1f19f094a5696fd18f4o7",
                  "id": "44e1f19f094a5696fd18f4o7",
                  "parent": "62e1f19f094a5696fd18f4e9",
                  "children": [
                        {
                            "_id": "62e1f19f094a5696fd18f4e9",
                            "id": "62e1f19f094a5696fd18f4e9",
                            "parent": "44e1f19f094a5696fd18f4o7",
                            "children": []
                        }
                   ] 
              }
        ] 
    }

Upvotes: 1

Views: 152

Answers (1)

nimrod serok
nimrod serok

Reputation: 16033

Based on a question by @rickhg12hs:

It can be done, but I agree with @turivishal that if you are doing it, it is reasonable to store it once (a minor change to the query):

db.collection.aggregate([
  {
    $replaceRoot: {
      newRoot: {
        $function: {
          body: "function drill(r) {r.id = r._id; if (r.children.length > 0) { for (let elem of r.children) { drill(elem)}} return r};",
          args: [
            "$$ROOT"
          ],
          lang: "js"
        }
      }
    }
  }
])

See how it works on the playground example

For storing on the db, instead of aggregate use an update with pipeline, like this

Upvotes: 2

Related Questions