Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

made a few more clarifying changes

  • Loading branch information...
commit 02fcf1219f1955059a54aae535ae5ecdc1ac9a75 1 parent bb0374f
@dcrosta dcrosta authored
Showing with 15 additions and 16 deletions.
  1. +15 −16 content/patterns/track_max_value_in_array.txt
View
31 content/patterns/track_max_value_in_array.txt
@@ -29,23 +29,23 @@ 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:
@@ -53,7 +53,7 @@ The code for this operation resembles:
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`.
Please sign in to comment.
Something went wrong with that request. Please try again.