javascriptmongodbmongodb-queryrecursive-descent

MongoDB javascript `"$function"` not returning expected value in mongoplayground.net


N.B.: This is the first javascript function I've written. My question is inspired by another question inquiring about recursive descent within a MongoDB document.

I tried the function on jsfiddle.net and it works, but when I try it on mongoplayground.net, it doesn't work.

Input collection:

[
  {
    "_id": 0,
    "text": "Node1",
    "children": [
      {
        "text": "Node2",
        "children": []
      },
      {
        "text": "Node3",
        "children": [
          {
            "text": "Node4",
            "children": [
              {
                "text": "Node5",
                "children": []
              },
              {
                "text": "Node6",
                "children": []
              }
            ]
          },
          {
            "text": "Node7",
            "children": []
          }
        ]
      }
    ]
  }
]

mongoplayground.net aggregation pipeline:

db.collection.aggregate([
  {
    "$set": {
      "texts": {
        "$function": {
          "body": "function(t, n) {function drill(t, n) {if (n.length > 0) {for (let elem of n) {t.push(elem.text); drill(t, elem.children)}} return t};drill(t,n)}",
          "args": [
            [
              "$text"
            ],
            "$children"
          ],
          "lang": "js"
        }
      }
    }
  }
])

jsfiddle.net outputs the desired result, ["Node1", "Node2", "Node3", "Node4", "Node5", "Node6", "Node7"], but mongoplayground.net sets "texts" to null.

Is there a way to fix the MongoDB "$function" or is this a limitation of mongoplayground.net or MongoDB?


Solution

  • How about just removing the external function to get your desired results:

        db.collection.aggregate([
      {
        "$addFields": {
          "texts": {
            "$function": {
              "body": "function drill(t, n) {if (n.length > 0) {for (let elem of n) {t.push(elem.text); drill(t, elem.children)}} return t};",
              "args": [
                [
                  "$text"
                ],
                "$children"
              ],
              "lang": "js"
            }
          }
        }
      }
    ])
    

    You can see it works here