How to perform both a $set and a $push in the same update to my mongo collection

I have a document that looks like this (figure 1):

{
  "_id": "jcLh4exkHL7KsfuKB", 
    "device": {
      "mac": 1,
      "sds": 101,
      "ids": 11,
      "lvl": 90,
      "sde": [
        {
          "mType": 0,
          "mTs": 1449273600020,
          "pre": 50,
          "hum": 54,
          "temp": 70
        }
      ],
      "iType": 3,
      "iTs": 1449273600020,
      "mCount": 11,
      "fCount": 200
   }
}

The document has an array (sde) that needs to grow as more sensor data arrives, but the other fields only need to be updated, for example, like this (figure 2):

{
  "_id": "jcLh4exkHL7KsfuKB",
    "device": {
      "mac": 1,
      "sds": 1000,
      "ids": 12,
      "lvl": 85,
      "sde": [
        {
          "mType": 0,
          "mTs": 1449273600020,
          "pre": 50,
          "hum": 54,
          "temp": 70
        },
        {
          "mType": 0,
          "mTs": 1449273600030,
          "pre": 49,
          "hum": 53,
          "temp": 75
        }
      ],
      "iType": 0,
      "iTs": 1449273600020,
      "mCount": 15,
      "fCount": 500
   }
}

The problem is that I can only update at the device:{} level or the sde:{[]} level, but not both. I donā€™t get any errors, the update simply ā€˜completesā€™.

Here is the code I am attempting to get working:

myCollection.update({
          _id: thisDevice._id // I am getting the _id based on a device.mac query elsewhere
        },{
          // set block - update message header & footer - non-array
          $set: {
           'device.mCount': this.request.body.device.mCount,
            'device.fCount': this.request.body.device.fCount,
            'device.iType': this.request.body.device.iType,
            'device.sds': this.request.body.device.sds,
            'device.ids': this.request.body.device.ids,
            'device.lvl': this.request.body.device.lvl,
            'device.iTs': this.request.body.device.iTs
          }
        },{
          // push block - add message array element
          $push: {
            'device.sde': {
              $each: this.request.body.device.sde
            }
          }
        });

As the code is written, I can update everything in the set block, but nothing in the push block.

If I comment the set block, the push block works perfectly.

How can I get both the set and push blocks working so that I can realize the result in figure 2?

What you have done is put the $push in the options argument instead of the query argument. Put it in the same object as $set, like this: {$set:{},$push:{}}

3 Likes

Yep, thatā€™s it. I looked at that for hours and still couldā€™t spot the obvious error. Still learningā€¦thanks for the help!

1 Like