Search code examples
javascriptnode.jsmongodbmongoose

Can not apply upsert when updating empty array item in Mongodb


My db looks like:

[
  {
    id: 10,
    markets: []
  }
]

When I perform:

db.collection.update({
  id: 10
},
{
  $set: {
    "markets.$[element]": {
      eventId: 1,
      happy: 2
    },
  },
},
{
  arrayFilters: [
    {
      element: {
        eventId: 1,
      },
    },
  ],
  upsert: true,
})

Result:

[
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "id": 10,
    "markets": []
  }
]

However, when I changed the db to:

[
  {
    id: 10,
    markets: [
      {
        eventId: 1
      }
    ]
  }
]

The update works. I wish to apply upsert here, so even if markets=[], I can still insert/add the object into db when eventId is not exist in the array.


Solution

  • Upsert works only on documents, not on single fields.

    One solution is this one:

    db.collection.updateOne(
       { id: 10 },
       [
          {
             $set: {
                markets: {
                   $concatArrays: [
                      { $filter: { input: "$markets", cond: { $ne: ["$$this.eventId", 1] } } },
                      [{
                         eventId: 1,
                         happy: 2
                      }]
                   ]
                }
             }
          }
       ]
    )
    

    Mongo Playground

    However, it will change the order of market elements.