Skip to content
Permalink
Browse files

made a few more clarifying changes

  • Loading branch information
dcrosta committed Dec 17, 2011
1 parent bb0374f commit 02fcf1219f1955059a54aae535ae5ecdc1ac9a75
Showing with 15 additions and 16 deletions.
  1. +15 −16 content/patterns/track_max_value_in_array.txt
@@ -29,31 +29,31 @@ comparisons when updating--that is, there is no operator which will
update a value *if and only if* it is greater than the existing
value. Such an operator would render this recipe trivial.

However, you can accomplish this task with a series of two invocations
of the `findAndModify` command:
However, you can accomplish this task with two invocations of the
`findAndModify` command:

1. Issue a `findAndModify` that sets the `max_value` and pushes to the
array at the same time. This operation only succeeds if the
`max_value` is less than the new value.
`max_value` is less than or equal to the new value.

2. If the previous operation fails, then fails because another update
has increased `max_value` since step 1. By definition, the existing
value is now more than the new value. so it is safe to push the new
2. If the previous operation fails, it can only be because `max_value`
is already greater than the new value, so it is safe to push the new
value without regard for `max_value`.


To obtain the result of the `findAndModify` command, take the first
result that succeeds and assign it to the `result` variable. Because
`findAndModify` only runs for a second or third time if the preceding
operations made no updates, then we know that there can only ever be a
single value of `result`.
result that succeeds and assign it to the `result` variable. Because the
second `findAndModify` only runs if the preceding operations made no
updates, then we know that there can only ever be a single value of
`result`.

The code for this operation resembles:

<% code 'javascript' do %>
var result1 = null, result2 = null;

result1 = db.collection.findAndModify({
query: {_id: ObjectId(...), max_value: {$lt: new_value}},
query: {_id: ObjectId(...), max_value: {$lte: new_value}},
update: {$push: {array: new_value}, $set: {max_value: new_value}}});

if (result1 === null ) {
@@ -67,11 +67,10 @@ var result = result1 || result2;

## Variations

If you want the `result` variable to contain the entire updated
document, rather than the version that existed before the
`findAndModify` command that succeeded, add `new: true` to the
If you want the `result` variable to include the changes made by
whichever of the two `findAndModify`s succeeded, add `new: true` to the
arguments to `findAndModify`.

If you want the `array` attribute of the document to contain a set of
values, rather than an array of all values pushed, use the `$addToSet`
operator rather than `$push`.
unique values, rather than an array of all values pushed, use the
`$addToSet` operator rather than `$push`.

0 comments on commit 02fcf12

Please sign in to comment.
You can’t perform that action at this time.