1

I have a recursive structure in one of my MongoDB collections, like so:

{
    "id": String,
    "date": Date,
    "text": String
    "replies": [{
        // Same structure as above
    }]
}

I need to update a document in this hierarchy by adding in a reply to a nested document. The guarantees are as follows:

  • The object to reply to is guaranteed to exist.
  • The path to the object to which a reply is to be posted is known (i.e., we have a sequence of the _id attributes to navigate).
  • The recursion depth is not bounded.

Searching SO gives me the following relevant questions:

Based on the latter, my attempt was:

await commCollection.update(
    { _id: topLevel['_id'] },
    {
        $push: {
            'replies.$[].$[comment_arr].replies': {
                id: commentId,
                text: comment,
                date,
                replies: []
            }
        }
    },
    { arrayFilters: [{ 'comment_arr.id': responseTo }]}
);

where topLevel is the root document, responseTo is the id attribute of the object to add the reply to. This however, does not seem to work. What am I doing wrong, and how do I achieve this?

Update: An example below. Here's an example of a document from MongoDB Atlas:

{
    "_id": {
        "$oid": "605fdb8d933c5f50b4d2225e"
    },
    "id": "mr9pwc",
    "username": "recrimination-logistical",
    "upvotes": {
        "$numberInt": "0"
    },
    "downvotes": {
        "$numberInt": "0"
    },
    "text": "Top-level comment",
    "date": {
        "$date": {
            "$numberLong": "1616894861300"
        }
    },
    "replies": [{
        "id": "dflu1h",
        "username": "patrolman-hurt",
        "upvotes": {
            "$numberInt": "0"
        },
        "downvotes": {
            "$numberInt": "0"
        },
        "text": "Testing reply level 1!",
        "date": {
            "$date": {
                "$numberLong": "1618387567042"
            }
        },
        "replies": []    // ----> want to add a reply here
    }]
}

I've indicated where we want a reply added. responseTo in this case would be dflu1h.

Rahul
  • 1,056
  • 2
  • 9
  • 26

1 Answers1

0
  • Just need to remove $[] positional
  • Field name in arrayFilters must be an alphanumeric string beginning with a lowercase letter, Change comment_arr to any alphabets only like commentArr, remove special characters
await commCollection.update(
  { _id: topLevel['_id'] },
  {
    $push: {
      "replies.$[commentArr].replies": {
        id: commentId,
        text: comment,
        date,
        replies: []
      }
    }
  },
  { arrayFilters: [{ "commentArr.id": responseTo }] }
)

Playground

turivishal
  • 34,368
  • 7
  • 36
  • 59