0

I have a seemingly straight forward query to update the names of like objects in a mongo doc. But it fails as not all docs have comment.. what should i be looking for in the docs get around this and update only the docs that have likes on comments?

    return this.model.updateMany(
      { 
        comments: { 
           $exists: true 
        } 
      },
      {
        $set: {
          'comments.likes.$[like].actor.firstName': user.firstName,
          'comments.likes.$[like].actor.lastName': user.lastName,
        },
      },
      {
        multi: true,
        arrayFilters: [
          { 'like.actor.username': user.username },
        ],
      },
    );

The problem is that not all comments are liked.. so then the query complains:

WriteError: The path 'comments.likes' must exist in the document in order to apply array updates. 

Full output:

WriteError: The path 'comments.likes' must exist in the document in order to apply array updates. 
Details:
WriteError({
    "index" : 0,
    "code" : 2,
    "errmsg" : "The path 'comments.likes' must exist in the document in order to apply array updates.",
    "op" : {
        "q" : {
            "comments" : {
                "$exists" : true
            }
        },
        "u" : {
            "$set" : {
                "comments.likes.$[like].actor.firstName" : "GGGJOHN",
                "comments.likes.$[like].actor.lastName" : "Carmichael"
            }
        },
        "multi" : true,
        "upsert" : false,
        "arrayFilters" : [
            {
                "like.actor.username" : "john.carmichael"
            }
        ]
    }
})
WriteError@src/mongo/shell/bulk_api.js:461:48
Bulk/mergeBatchResults@src/mongo/shell/bulk_api.js:841:49
Bulk/executeBatch@src/mongo/shell/bulk_api.js:906:13
Bulk/this.execute@src/mongo/shell/bulk_api.js:1150:21
DBCollection.prototype.updateMany@src/mongo/shell/crud_api.js:655:17
@(shell):1:1

Here is an illustration of the doc in q, where comments is an array and the likes on a single comment is also an array: enter image description here

  • Hi, did you ever figure this out? I am having the same issue. It is almost like the exists is needed as part of the array filters for some reason. – Leia Feb 02 '21 at 03:48
  • 1
    For the record I was able to solve my problem with this answer: https://stackoverflow.com/questions/58555989/how-to-find-and-update-nested-array-element-in-an-object-on-mongodb – Leia Feb 02 '21 at 03:57
  • I didn't i coded in a filthy hack - thanks for the link –  Feb 04 '21 at 07:26

1 Answers1

0

what if you added under match part of the update part query you are checking if likes attribute exists in the comments object

return this.model.updateMany(
  { 
   "comments.likes": {  // <---
       $exists: true 
    } 
  },
  {
    $set: {
      'comments.likes.$[like].actor.firstName': user.firstName,
      'comments.likes.$[like].actor.lastName': user.lastName,
    },
  },
  {
    multi: true,
    arrayFilters: [
      { 'like.actor.username': user.username },
    ],
  },
);
Anurag Wagh
  • 1,086
  • 6
  • 16
  • that doesn't work either, nor does adding comments and likes to the match. –  Oct 19 '20 at 16:39