Database Reference
In-Depth Information
$inc: {helpful_votes: 1}
})
This is almost correct. But you need to ensure that the update happens only if the vot-
ing user hasn't yet voted on this review. So you modify the query selector to match
only when the voter_ids array doesn't contain the ID you're about to add. You can
easily accomplish this using the $ne query operator:
query_selector = {_id: ObjectId("4c4b1476238d3b4dd5000041"),
voter_ids: {$ne: ObjectId("4c4b1476238d3b4dd5000001")}}
db.reviews.update(query_selector,
{$push: {voter_ids: ObjectId("4c4b1476238d3b4dd5000001")},
$inc : {helpful_votes: 1}
})
This is an especially powerful demonstration of MongoDB's update mechanism and
how it can be used with a document-oriented schema. Voting, in this case, is both
atomic and efficient. The atomicity ensures that, even in a high-concurrency environ-
ment, it'll be impossible for any one user to vote more than once. The efficiency lies
in the fact that the test for voter membership and the updates to the counter and the
voter list all occur in the same request to the server.
Now, if you do end up using this technique to record votes, it's especially impor-
tant that any other updates to the review document also be targeted. This is because
updating by replacement could conceivably result in an inconsistency. Imagine, for
instance, that a user updates the content of their review and that this update occurs
via replacement. When updating by replacement, you first query for the document
you want to update. But between the time that you query for the review and replace it,
it's possible that a different user might vote on the review. This sequence of events is
illustrated in figure 6.4.
It should be clear that the document replacement at T3 will overwrite the votes
update happening at T2. It's possible to avoid this using the optimistic locking
Review documents
{:text => "Awesome",
:votes => 3}
{:text => "Awesome",
:votes => 4}
{:text => "Incredible!",
:votes => 3}
T1
T2
T3
Processes
Process 2 at T2
Updates votes on
review
Process 1 at T1
Queries for a review
Process 1 at T3
Replaces review
Figure 6.4
When a review is updated concurrently via targeted and replacement updates, data
can be lost.
Search WWH ::




Custom Search