Search code examples
mongodbmongodb-querymongodb-update

Set same value on multiple fields


I have the following document structure:

{
    ...
    timings: {
        mon: "",
        tue: "",
        wed: "",
        thu: "",
        fri: "",
        sat: "",
        sun: "",
    }
    ...
}

I want to set the value "Open 24 Hours" for all the days of the week.

Currently I am using the query:

db.collection.update({_id: ObjectId("someId")}, {$set: {"timings.mon": "Open 24 Hours"}});

And then running the same for the rest of the days of the week.

I can also set all the fields in the same query explicitly, but it's faster to just change the day and run it again.

Is there a way to set the value of multiple fields in a subdocument in a more efficient way?

UPDATE

I tried the following query, but it doesn't work:

db.collection.update({_id: ObjectId("someId")}, {$set: {"timings.$": "Open 24 Hours"}});

Solution

  • You could try first creating the update object where you can set the multiple fields of that object before updating the document this way:

    var days = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"],
        timings = {},
        query = {"_id" : ObjectId("554e12e4674dec7517e692eb")},
        update = {
            "$set": { "timings": timings }
        },
        options = {"upsert": true};
    
    days.forEach(function (day){ timings[day] = "Open 24 Hours" });
    db.collection.update(query, update, options);
    

    Querying the collection for that document using db.collection.findOne(query) will yield:

    /* 0 */
    {
        "_id" : ObjectId("554e12e4674dec7517e692eb"),
        "timings" : {
            "mon" : "Open 24 Hours",
            "tue" : "Open 24 Hours",
            "wed" : "Open 24 Hours",
            "thu" : "Open 24 Hours",
            "fri" : "Open 24 Hours",
            "sat" : "Open 24 Hours",
            "sun" : "Open 24 Hours"
        }
    }
    

    -- UPDATE --

    Another approach (as suggested by @Michael in the comments) is to use the JavaScript's native Object.keys() method which returns an array of a given object's own enumerable properties, in the same order as that provided by a for...in loop (the difference being that a for-in loop enumerates properties in the prototype chain as well):

    > var days = Object.keys(db.collection.findOne().timings);
    > print(days);
    mon,tue,wed,thu,fri,sat,sun
    >
    

    And thus can be implemented as:

    var days = Object.keys(db.collection.findOne().timings),
        timings = {},
        query = {"_id" : ObjectId("554e12e4674dec7517e692eb")},
        update = {
            "$set": { "timings": timings }
        },
        options = {"upsert": true};