MongoDB $max

MongoDB has a $max operator that allows you to update the value of a field only if the specified value is greater than the current value of the field.

In other words, if the $max value is greater than the current value in the document, the $max value is used. Otherwise, the document’s value remains unchanged.

Example

Suppose we have a collection like this:

{ "_id" : 1, "exercise" : "deadlift", "bestLift" : 230 }
{ "_id" : 2, "exercise" : "benchpress", "bestLift" : 100 }
{ "_id" : 3, "exercise" : "squat", "bestLift" : 210 }

And imagine that we update the collection after each workout with out latest lifts. In this case, we would only want the bestLift field to be updated if our latest lift was heavier than our previous best lift (i.e. the current weight listed for the respective lift).

In this case we could use the $max operator to achieve that outcome.

Example:

db.workout.update( 
  { _id: 1 }, 
  { $max: { bestLift: 240 } } 
)

Output:

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

This message tells us that one document matched and was updated.

Let’s check the collection again.

db.workout.find()

Result:

{ "_id" : 1, "exercise" : "deadlift", "bestLift" : 240 }
{ "_id" : 2, "exercise" : "benchpress", "bestLift" : 100 }
{ "_id" : 3, "exercise" : "squat", "bestLift" : 210 }

We can see that the bestLift field for the first document was updated with the new value. This is because 240 is higher than its previous value of 230.

When the Value is Lower

When the value specified with $max is lower than the existing value in the document, nothing is updated.

Example:

db.workout.update( 
  { _id: 1 }, 
  { $max: { bestLift: 220 } } 
)

Output:

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })

We can see by the message that nothing was updated.

Let’s check the collection again.

db.workout.find()

Result:

{ "_id" : 1, "exercise" : "deadlift", "bestLift" : 240 }
{ "_id" : 2, "exercise" : "benchpress", "bestLift" : 100 }
{ "_id" : 3, "exercise" : "squat", "bestLift" : 210 }

We can see that the value remains at 240, even though we tried to update it to 220. This is expected, because we used $max.

Dates

You can use $max on date fields.

Suppose we have a collection called subscriptions with the following document:

{ "_id" : 1, "expiry" : ISODate("2021-01-01T00:00:00Z") } 

Let’s try to update the date with a date that’s earlier than the current date in the document.

db.subscriptions.update( 
  { _id: 1 }, 
  { $max: { expiry: new Date("2020-01-01") } } 
)

Here, we try to update the year from 2021 to 2020. Given the new date is earlier than the existing one, we get the following.

db.subscriptions.find()

Result:

{ "_id" : 1, "expiry" : ISODate("2021-01-01T00:00:00Z") }

As expected, nothing was updated.

Let’s try to update it with a later date.

db.subscriptions.update( 
  { _id: 1 }, 
  { $max: { expiry: new Date("2022-01-01") } } 
)

Output:

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

We can see by the message that the document was updated.

Let’s check.

db.subscriptions.find()

Result:

{ "_id" : 1, "expiry" : ISODate("2022-01-01T00:00:00Z") }

The date was updated as expected.