1

更新:我建议阅读我接受的答案,它为您提供了解决此问题的不同方法。

我有以下收藏。

{
        "_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")
                }
        ]
}

如果存在,我想更新“事件”数组中的文档(我想通过 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 操作的东西。

4

2 回答 2

1

我认为您仍然需要通过两个查询来执行此操作。但是,使用$ 查询to update,您可以在 EID 已经存在的情况下将其保留为一个查询。

db.col.update({"events.eid": 2}}, {$set: {"events.$.title: "Event 4", "events.$.start": new Date(2013, 08, 02}})

如果它的返回值表明没有找到记录,那么您可以插入它。

于 2013-08-01T13:04:18.573 回答
0

更新
像上面那样收集来对文档进行分组是很明显的心态。但是将文档放在数组中会导致其他一些问题。您必须使用Array Update运算符来更新每个文档。相反,我重组了我的收藏,如下所示。另外,请参阅这个google 小组讨论。正如“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); 

这似乎很有希望。

于 2013-08-01T13:30:54.637 回答