更新:我建议您阅读我接受的答案,这会为您解决此问题。
我收集了以下内容。
{
"_id" : ObjectId("51fa56408e843042c0c24e3d"),
"uniqDates" : [
ISODate("2013-07-30T18:30:00Z"),
ISODate("2013-07-31T18:30:00Z")
]
}
{
"_id" : ObjectId("51fa5648c424ea3e37199502"),
"events" : [
{
"eid" : 1,
"title" : "Event 1",
"start" : ISODate("2013-08-04T18:30:00Z")
},
{
"eid" : 2,
"title" : "Event 2",
"start" : ISODate("2013-08-08T18:30:00Z")
}
]
}
我想更新“events”数组中的文档(如果它存在(我想通过eid检查),如果它不存在我想插入该文档。
目前我这样做有两个问题。
db.col.update({events: {$exists: 1}}, {$pull: {"events": {"eid": 2}}});
和
db.schedule.update({events: {$exists: 1}}, {$addToSet:
{"events": {"eid": 2, "title": "Event 4", "start": new Date(2013, 08, 02)}}});
有没有办法用单一查询执行此操作?一些有upsert操作的东西。
答案 0 :(得分:1)
我认为你仍然需要用两个查询来做这件事。但是,使用$ query到update
,您可以在EID已存在的情况下将其保留为一个查询。
db.col.update({"events.eid": 2}}, {$set: {"events.$.title: "Event 4", "events.$.start": new Date(2013, 08, 02}})
如果返回值表示没有找到记录,则可以插入它。
答案 1 :(得分:0)
的更新强>
将上述集合用于分组文档是非常明显的心态。
但是在数组中包含文档会导致一些其他问题。您
必须让Array Update运营商更新每个运营商
文献。相反,我重新构建了我的收藏,如下所示。也,
见google group discussion。由于“idbentley”在那里指定
是否有可能超过文档大小限制(16 MB)
导致数据碎片化。因此,在为数据建模时要有意识。
原始答案
似乎无法在文档数组中实现upsert操作。所以改变了我的架构设计,如下所示。
{
"_id" : ObjectId("51fa619a8e843042c0c24e46"),
"uniqDates" : [
ISODate("2013-07-30T18:30:00Z"),
ISODate("2013-07-31T18:30:00Z")
]
}
{
"_id" : ObjectId("51fa61b38e843042c0c24e47"),
"eid" : 1,
"title" : "Event 1",
"start" : ISODate("2013-08-04T18:30:00Z")
}
{
"_id" : ObjectId("51fa61b38e843042c0c24e48"),
"eid" : 2,
"title" : "Event 2",
"start" : ISODate("2013-08-08T18:30:00Z")
}
查找事件:
db.schedule.find({"eid": {$exists: 1}});
要查找唯一日期:
db.schedule.find({"uniqDates": {$exists: 1}});
实现'upsert'操作:
db.schedule.update({"eid": 3}, {"eid": 3, "title": "Event 3",
"start": new Date(2013, 05, 06)}, true);
这看起来很有希望。