MongoDB $nin Query Operator

In MongoDB, the $nin query operator selects the documents where the field’s value is not in the specified array or where the field doesn’t exist.

Example

Suppose we have a collection called products with the following documents:

{ "_id" : 1, "prod" : "Bat", "sizes" : [ "S", "M", "XL", "XXL" ] }
{ "_id" : 2, "prod" : "Hat", "sizes" : [ "S", "L", "XL" ] }
{ "_id" : 3, "prod" : "Cap", "sizes" : [ "XS", "S", "M", "L", "XL" ] }
{ "_id" : 4, "prod" : "Shirt", "sizes" : "L" }
{ "_id" : 5, "prod" : "Jeans", "sizes" : null }
{ "_id" : 6, "prod" : "Shorts" }

We can use the $nin operator to select just those documents that don’t have specific _id values.

Example code:

db.products.find({ 
  _id: { $nin: [ 1, 2, 3 ] } 
})

Result:

{ "_id" : 4, "prod" : "Shirt", "sizes" : "L" }
{ "_id" : 5, "prod" : "Jeans", "sizes" : null }
{ "_id" : 6, "prod" : "Shorts" }

In this case, we only wanted documents that don’t contain an _id value of 1, 2, or 3.

Example 2

Here’s another example. This time we use $nin against a different field.

db.products.find({ 
  sizes: { $nin: [ "L" ] } 
})

Result:

{ "_id" : 1, "prod" : "Bat", "sizes" : [ "S", "M", "XL", "XXL" ] }
{ "_id" : 5, "prod" : "Jeans", "sizes" : null }
{ "_id" : 6, "prod" : "Shorts" }

In this example we applied $nin to the sizes field.

Notice that document 6 was returned, even though it doesn’t have a sizes field. This is exactly as expected – if the field doesn’t exist, it’s included in the $nin results.

Comparison of different types are evaluated according to the BSON comparison order.

Aggregation Example

We can use the same syntax when using the $match aggregation pipeline operator.

Example code:

db.products.aggregate(
   [
     { $match: { _id: { $nin: [ 1, 2, 3 ] } } }
   ]
)

Result:

{ "_id" : 4, "prod" : "Shirt", "sizes" : "L" }
{ "_id" : 5, "prod" : "Jeans", "sizes" : null }
{ "_id" : 6, "prod" : "Shorts" }

And here it is again while querying the sizes field:

db.products.aggregate(
   [
     { $match: { sizes: { $nin: [ "L" ] } } }
   ]
)

Result:

{ "_id" : 1, "prod" : "Bat", "sizes" : [ "S", "M", "XL", "XXL" ] }
{ "_id" : 5, "prod" : "Jeans", "sizes" : null }
{ "_id" : 6, "prod" : "Shorts" }

Regular Expressions

You can use regular expressions in the query by using the form /pattern/.

Example:

db.products.find({ 
  sizes: { $nin: [ /^X/ ] } 
})

Result:

{ "_id" : 4, "prod" : "Shirt", "sizes" : "L" }
{ "_id" : 5, "prod" : "Jeans", "sizes" : null }
{ "_id" : 6, "prod" : "Shorts" }

In this example, I return all documents that do not have a sizes field that starts with X.