3

我有以下文档结构:

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

我想为一周中的所有日子设置“24 小时开放”的值。

目前我正在使用查询:

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

然后在一周的其余日子里运行相同的。

我也可以显式地设置同一查询中的所有字段,但只需更改日期并再次运行它会更快。

有没有办法以更有效的方式设置子文档中多个字段的值?

更新

我尝试了以下查询,但它不起作用:

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

1 回答 1

4

您可以尝试首先创建更新对象,您可以在以这种方式更新文档之前设置该对象的多个字段:

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);

使用查询该文档的集合db.collection.findOne(query)将产生:

/* 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"
    }
}

--更新--

另一种方法(正如@Michael 在评论中所建议的那样)是使用 JavaScript 的本机Object.keys()方法,该方法返回给定对象自己的可枚举属性的数组,其顺序与 for...in 循环提供的顺序相同(区别在于for-in 循环也枚举原型链中的属性):

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

因此可以实现为:

var days = Object.keys(db.collection.findOne().timings),
    timings = {},
    query = {"_id" : ObjectId("554e12e4674dec7517e692eb")},
    update = {
        "$set": { "timings": timings }
    },
    options = {"upsert": true};
于 2015-05-09T14:09:12.820 回答