Incrementing a counter only successful addtoset.

817 views
Skip to first unread message

Boyd

unread,
Apr 21, 2011, 11:39:47 AM4/21/11
to mongodb-user
Preface: I'm a few days new to mongo and have been creating a MVC
project to interact with mongo. I have been using the
https://github.com/mongodb/mongo-csharp-driver and have been writing
my own layer on top of it.

So I'm trying to do an atomic operation where I add a value to an
array and increment a counter for the array. This is a common scenario
and I do not have trouble doing this. However, I am making certain
that I do not insert a duplicate value. Mongo has built in support for
this feature as I've been able to use 'addtoset' to ensure no
duplicates are placed, however the increment still happens. Which puts
the counter out of synch with the actual amount in the array.

I was hoping to do this in an atomic operation: so I tried to create
the following query:

update( {_id:'123', array: {"$ne": "456"}},
{"$addtoset": { array: "456" } , $inc: { counter : 1 }} )

When 456 does not exist in the array, then the statement works fine.
However, when 456 does exist in the array, then I get the following:

MongoDB.Driver.MongoCommandException : Command 'findAndModify' failed:
No matching object found (response: { "errmsg" : "No matching object
found", "ok" : 0 })

Am I taking the right approach here? Is there a feature, override, or
command I am missing? Is there another way to 'chain' operators on
success?

Brian O'Connor

unread,
Apr 21, 2011, 11:43:45 AM4/21/11
to mongod...@googlegroups.com
Yes, that is the approach we use as well.  I'm not sure about the csharp driver, but in pymongo we do the findandmodify in a try/except block.  If the exception is triggered, we know it was a duplicate, and handle appropriately.


--
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.




--
Brian O'Connor

Boyd

unread,
Apr 21, 2011, 4:37:42 PM4/21/11
to mongodb-user
Thanks for the quick reply. I wasn't expecting it to throw exceptions
for all failed findandmodify operations. I thought something went
horribly wrong as is usually the case with exceptions. I figured it
would just fail, or return false for the success property on the
result response. Well, at least I know now what to look for now; I'll
have to keep in mind the c# driver is eager to throw exceptions rather
than fail. =(

Thanks.

On Apr 21, 11:43 am, "Brian O'Connor" <gatzby...@gmail.com> wrote:
> Yes, that is the approach we use as well.  I'm not sure about the csharp
> driver, but in pymongo we do the findandmodify in a try/except block.  If
> the exception is triggered, we know it was a duplicate, and handle
> appropriately.
>
>
>
>
>
>
>
>
>
> On Thu, Apr 21, 2011 at 11:39 AM, Boyd <thas...@gmail.com> wrote:
> > Preface: I'm a few days new to mongo and have been creating a MVC
> > project to interact with mongo. I have been using the
> >https://github.com/mongodb/mongo-csharp-driverand have been writing

Brian O'Connor

unread,
Apr 21, 2011, 4:48:37 PM4/21/11
to mongod...@googlegroups.com

I can't speak to the csharp driver, but in pymongo you can specify 'check=False' which will not raise an error if no object was found and return an error status instead.

Maybe something like that exists in the csharp driver, might be worth taking a look.

Robert Stam

unread,
Apr 21, 2011, 5:01:49 PM4/21/11
to mongodb-user
The C# driver throws an exception if the server responds that an error
occurred. It doesn't examine the error message to decide how serious
the error might be (that's up to you to decide).

The server considers it an error if FindAndModify doesn't find a
matching document to modify.

But you can use Update instead. Update doesn't care if zero documents
match the query, and the server doesn't respond with an error and
therefore no exception is thrown.

On Apr 21, 4:48 pm, "Brian O'Connor" <gatzby...@gmail.com> wrote:
> I can't speak to the csharp driver, but in pymongo you can specify
> 'check=False' which will not raise an error if no object was found and
> return an error status instead.
>
> Maybe something like that exists in the csharp driver, might be worth taking
> a look.
> On Apr 21, 2011 4:37 PM, "Boyd" <thas...@gmail.com> wrote:
>
> > Thanks for the quick reply. I wasn't expecting it to throw exceptions
> > for all failed findandmodify operations. I thought something went
> > horribly wrong as is usually the case with exceptions. I figured it
> > would just fail, or return false for the success property on the
> > result response. Well, at least I know now what to look for now; I'll
> > have to keep in mind the c# driver is eager to throw exceptions rather
> > than fail. =(
>
> > Thanks.
>
> > On Apr 21, 11:43 am, "Brian O'Connor" <gatzby...@gmail.com> wrote:
> >> Yes, that is the approach we use as well.  I'm not sure about the csharp
> >> driver, but in pymongo we do the findandmodify in a try/except block.  If
> >> the exception is triggered, we know it was a duplicate, and handle
> >> appropriately.
>
> >> On Thu, Apr 21, 2011 at 11:39 AM, Boyd <thas...@gmail.com> wrote:
> >> > Preface: I'm a few days new to mongo and have been creating a MVC
> >> > project to interact with mongo. I have been using the
> >> >https://github.com/mongodb/mongo-csharp-driverandhave been writing

Robert Stam

unread,
Apr 21, 2011, 5:45:41 PM4/21/11
to mongodb-user
Turns out there's a JIRA related to this also:

https://jira.mongodb.org/browse/SERVER-2757

The server is being modified so that findAndModify does not return an
error when no matching document is found.

Some of the drivers have been modified to ignore this one particular
error returned from the server from findAndModify. I suppose the C#
driver should be modified in the same way...
> > >> >https://github.com/mongodb/mongo-csharp-driverandhavebeen writing

Keith Branton

unread,
Apr 21, 2011, 6:27:58 PM4/21/11
to mongod...@googlegroups.com
@Boyd, See this jira too:


Your approach is fine, but with that jira you would be able to make other changes in the same operation too, if you wanted.

btw - with the gating you are doing on your query, you could just $push instead of $addToSet - not that it is likely to matter, but $push is possibly a little quicker since it doesn't have to check the elements of the array.

Boyd

unread,
Apr 28, 2011, 10:56:15 AM4/28/11
to mongodb-user
Thanks guys for pointing out those Jira issues, glad I wasn't alone.

@Robert,

Thanks for the tip. I am using Update now without and got rid of my
exception handling. Much better now! I only needed a query and update
command, I didn't need the extra parameters of findandmodify so I was
able to port it over effortlessly. If I need to use findandmodify
again I'll keep this all in mind.

Thanks everyone.

Robert Stam

unread,
Apr 28, 2011, 11:02:01 AM4/28/11
to mongodb-user
Regarding the original exception thrown by the C# driver on
FindAndModify, we have modified the C# driver to no longer throw an
exception if no matching document is found:

https://jira.mongodb.org/browse/CSHARP-214

Several other drivers also swallow this error, and the server is going
to be changed as well to not consider no matching document an error.
Reply all
Reply to author
Forward
0 new messages