Mongodb upsert embedded document

mongodb

Solution

I think what you want is the $addToSet command - that will push an element to an array only if it does not already exist. I've simplified your example a bit for brevity:

db.meters.findOne()
{
    "_id" : ObjectId("4f8e95a718bc9c7da1e6511a"),
    "config" : {
        "someparam" : 4.5
    },
    "data" : [
        {
            "Meter" : 123456789,
        }
    ],
    "key" : "20120418_123456789"
}

Now run:

db.meters.update({"key" : "20120418_123456789"}, {"$addToSet": {"data" : {"Meter" : 1234}}})

And we get the updated version:

db.meters.findOne()
{
    "_id" : ObjectId("4f8e95a718bc9c7da1e6511a"),
    "config" : {
        "someparam" : 4.5
    },
    "data" : [
        {
            "Meter" : 123456789,
        },
        {
            "Meter" : 1234
        }
    ],
    "key" : "20120418_123456789"
}

Run the same command again and the result is unchanged.

Note: you are likely going to be growing these documents, especially if this field is unbounded and causing frequent (relatively expensive) moves by updating in this way - you should have a look here for ideas on how to mitigate this:

http://www.mongodb.org/display/DOCS/Padding+Factor#PaddingFactor-ManualPadding

Problem

I have a document per day per meter. How can I add another subdocument in the data array and create the whole document if he doesn't exists ? ``` { "key": "20120418_123456789", "data":[ { "Meter": 123456789, "Dt": ISODate("2011-12-29T16:00:00.0Z"), "Energy": 25, "PMin": 11, "PMax": 16 } ], "config": {"someparam": 4.5} } ``` Can I use upsert for that purpose ? The result will be if document exists : ``` { "key": "20120418_123456789", "data":[ { "Meter": 123456789, "Dt": ISODate("2011-12-29T16:00:00.0Z"), "Energy": 25, "PMin": 11, "PMax": 16 }, { "Meter": 123456789, "Dt": ISODate("2011-12-29T16:15:00.0Z"), "Energy": 22, "PMin": 13, "PMax": 17 } ], "config": {"someparam": 4.5} } ``` Thanks in advance

Original source