Skip to content

Instantly share code, notes, and snippets.

@bearzk
Last active August 10, 2023 13:22
Show Gist options
  • Save bearzk/935efd98cbbe127ad519ffcd4ac6d8dc to your computer and use it in GitHub Desktop.
Save bearzk/935efd98cbbe127ad519ffcd4ac6d8dc to your computer and use it in GitHub Desktop.

Idempotent array push

db.myRecords.findAndModify(
    {
      _id: recordId, 
      itemArray: {$not: { $elemMatch: { itemId: newItem.id } }}
    },
    { 
      $push: {itemArray: newItem}
    }
);

We have to be careful about the matching condition and the content we want to push into the array, we don't want to push wrong content with wrong matching conditions.

Let's look at this following example:

{
    "_id" : {
      "$oid": "64d4dfbe0e349e259d611b7b"
    },
    "people" : [
        {
            "name" : "lili",
            "loves" : "mario party"
        },
        {
            "name" : "miaozi",
            "loves" : "fire emblem"
        },
        {
            "name" : "kai",
            "loves" : "hollow knight"
        }
    ]
}

when we update it with the following query and update:

// query
{
  _id : ObjectId("64d4dfbe0e349e259d611b7b"),
  people: {$not: {$elemMatch: {name: 'not a thing'}}}
}

// update
{
  $push : {
    people: {
      name: 'kai',
      loves: 'cs'
    }
  }
}

will result in

{
    "_id" : ObjectId("64d4dfbe0e349e259d611b7b"),
    "people" : [
        {
            "name" : "lili",
            "loves" : "mario party"
        },
        {
            "name" : "miaozi",
            "loves" : "fire emblem"
        },
        {
            "name" : "kai",
            "loves" : "hollow knight"
        },
        {
            "name" : "kai",
            "loves" : "cs"
        }
    ]
}

we matched with not a thing but anyway pushed the object kai in there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment