1

UPDATE: I suggest to read my accepted answer, which gives you different approach on this problem.

I have following collection.

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

I want to update a document in "events" array if it exists (i want to check it by eid), if it doesn't exists i want to insert that document.

currently i am doing this with two queries.

db.col.update({events: {$exists: 1}}, {$pull: {"events": {"eid": 2}}});

and

db.schedule.update({events: {$exists: 1}}, {$addToSet: 
{"events": {"eid": 2, "title": "Event 4", "start": new Date(2013, 08, 02)}}});

Is there a way to do this with single query? Something with upsert operation.

1

2 Answers 2

1

I think you'll still need to do this with two queries. But, using a $ query to update, you can keep it to one query in the case where the EID already exists.

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

If the return value from that indicates that no records were found, then you can insert it instead.

Sign up to request clarification or add additional context in comments.

Comments

0

UPDATE
It is pretty obvious mindset to have collection like above to group documents. But having documents in array will result in some other problems. You have to suffer with Array Update operators to update each document. Instead, i restructured my collection as shown below. Also, see this google group discussion. As "idbentley" specified there is a possibility to exceed document size limit (16 MB) which will lead to data fragmentation. So be conscious while you model your data.

Original Answer

It seems like it is not possible to achieve upsert operation in document array. So changed my schema design like below.

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

To find events:

db.schedule.find({"eid": {$exists: 1}});

To find unique date:

db.schedule.find({"uniqDates": {$exists: 1}});

To achieve 'upsert' operation:

db.schedule.update({"eid": 3}, {"eid": 3, "title": "Event 3", 
                                "start": new Date(2013, 05, 06)}, true); 

This seems promising.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.