2

How can I update an embedded document in a set or insert one if it doesn't exist in single query? Say I have a document like below. And 'records' is a set of embedded documents.

{
    id: "1",
    records: [
        {userId:"5", userData: "..."},
        {userId:"12", userData: "..."},
        {userId:"27", userData: "..."}
    ]
}

I know how to insert or update 'records' in separate queries. But can I combine these queries so that it works similarly to MySQL's ON DUPLICATE KEY UPDATE? I want to avoid executing another query just to find out if an embedded document exists.

db.myCollection.update(
    {id:"1", records.userId:"12"},
    {records.$.userData:{"... new data ..."}}
);

db.myCollection.update(
    {id:"1"},
    {records:
        {$push:
            {userId: "33", userData: {"... new data ..."}}
        }
    }
);

Thanks

Jaepil
  • 390
  • 5
  • 20
  • Well I did have an answer, but Stack Overflow decided on converting it to a comment. – AlbertEngelB Sep 19 '12 at 01:59
  • Hi Na.z.Camp, do you still have a link to this 'comment' that you are referring to? – Jaepil Sep 19 '12 at 02:42
  • Possible duplicate of http://stackoverflow.com/q/10277174 – JohnnyHK Sep 19 '12 at 03:38
  • Thank JohnnyHK, I have also considered structuring the 'records' as an object. However this incurs the index issue the original questioner mentioned. And that won't be suitable for the type of data stored in 'records'. – Jaepil Sep 19 '12 at 04:31

1 Answers1

0

You could use Upsert

http://www.mongodb.org/display/DOCS/Updating#Updating-%7B%7Bupserts%7D%7D

SCB
  • 3,034
  • 2
  • 25
  • 24
  • Hi SCB, as far as I know upsert doesn't apply to **embedded** document. Please note I only want to modify main document's 'records' set. – Jaepil Sep 19 '12 at 02:41
  • Could you do it using a combination of the /*upsert*/ true on the update command and using the positional operator $? – SCB Sep 19 '12 at 03:18
  • 1
    @SCB, the MongoDB docs say "Do not use the positional operator $ with upsert operations because inserts will use the $ as a field name in the inserted document." See here: http://docs.mongodb.org/manual/reference/operator/positional/ – Kyle Cureau Feb 18 '13 at 03:53