"Update if Current" of embedded array item using C#

328 views
Skip to first unread message

Rainz

unread,
Jul 14, 2011, 8:39:15 PM7/14/11
to mongodb-user
Using the C# driver, is there a way to replace an element of an
embedded array only if it hasn't been changed since it was first
retrieved. In essence this would be an "Update if Current" of an
embedded array element.

For example let's say in STEP #1 I retrieve the following document:

{
"_id": {
"$oid": "4defe15e2a66bc11986859bb"
},
"widgets": [
{
"_id": "12312312",
"views": 3,
"comments": 7
},
{
"_id": "567567FF",
"views": 0,
"comments": 1
},
{
"_id": "890TT890",
"views": 2,
"comments": 8
}
],
"dtcreate": "Wed, 08 Jun 2011 16:53:51 GMT -04:00",
}

Then in STEP #2 I extract the object of widget "12312312" and make
some changes to it so the updated widget is:

{
"_id": "12312312",
"views": 5,
"comments": 9
}

Now in STEP #3 I use the positional operator to update only this
specific widget in the document.

Everything here works well, but the only problem is I wouldn't know if
another update happened to widget "12312312" between STEP #1 and STEP
#3.

What I'm seeking is a clean way to cancel the update in STEP #3 if any
update took place to the widget (or even the entire document if it
can't be done at the widget level) between #1 and #3.

Nat

unread,
Jul 14, 2011, 9:58:11 PM7/14/11
to mongod...@googlegroups.com
You would need to keep a version data or something that can identify version in there and use that as part of criteria.
http://www.mongodb.org/display/DOCS/Updating

Another option if u want to simply increment comments count of certain object. You can use update modifier $inc with $ positional operator.
http://www.mongodb.org/display/DOCS/Updating
--
You received this message because you are subscribed to the Google Groups "mongodb-user" group.
To post to this group, send email to mongod...@googlegroups.com.
To unsubscribe from this group, send email to mongodb-user...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/mongodb-user?hl=en.

Robert Stam

unread,
Jul 15, 2011, 10:23:45 AM7/15/11
to mongodb-user
If you add a version element to your document you can use it to track
changes to the document. I'll use an integer version number in the
example below, but an ObjectId is another possibility.

I'm working with this slightly different document (I've only changed
_ids to integers to make typing easier):

> db.test.find()
{ "_id" : 123, "version" : 1, "widgets" : [
{
"_id" : 0,
"views" : 3,
"comments" : 7
},
{
"_id" : 1,
"views" : 0,
"comments" : 1
},
{
"_id" : 2,
"views" : 2,
"comments" : 8
}
], "dtcreate" : ISODate("2011-07-15T14:08:47.257Z") }
>

Here's some sample shell code to simulate "extracting" the widget from
the document and updating it client side:

> var document = db.test.findOne()
> var widget = document.widgets[0]
> widget.views = 5
5
> widget.comments = 9
9
> widget
{ "_id" : 0, "views" : 5, "comments" : 9 }
>

Now we can use the findAndModify command to update the document while
making sure no one else has updated the document in the database in
the meantime:

> db.test.runCommand({
... findAndModify : "test",
... query : { _id : 123, version : document.version, "widgets._id" :
0 },
... update : { $inc : { version : 1 }, $set : { widget : widget } },
... new : true
... })
{
"value" : {
"_id" : 123,
"dtcreate" : ISODate("2011-07-15T14:08:47.257Z"),
"version" : 2,
"widget" : {
"_id" : 0,
"views" : 5,
"comments" : 9
},
"widgets" : [
{
"_id" : 0,
"views" : 3,
"comments" : 7
},
{
"_id" : 1,
"views" : 0,
"comments" : 1
},
{
"_id" : 2,
"views" : 2,
"comments" : 8
}
]
},
"ok" : 1
}
>

If we try and run the findAndModify command when the version numbers
don't match anymore we get:

> db.test.runCommand({
... findAndModify : "test",
... query : { _id : 123, version : document.version, "widgets._id" :
0 },
... update : { $inc : { version : 1 }, $set : { widget : widget } },
... new : true
... })
{ "errmsg" : "No matching object found", "ok" : 0 }



On Jul 14, 9:58 pm, "Nat" <nat.lu...@gmail.com> wrote:
> You would need to keep a version data or something that can identify version in there and use that as part of criteria.http://www.mongodb.org/display/DOCS/Updating
>
> Another option if u want to simply increment comments count of certain object. You can use update modifier $inc with $ positional operator.http://www.mongodb.org/display/DOCS/Updating

Rainz

unread,
Aug 4, 2011, 11:42:55 PM8/4/11
to mongodb-user
Thanks!

Worked nicely.
Reply all
Reply to author
Forward
0 new messages