While working on any project where we may have a requirement to check the size of an array or to get an element whose size is greater or less than a certain length. There are various ways to achieve this requirement with many MongoDB operators like $size, $where, $exists
, etc.
The below method can help you to resolve your issue related to array length or checking the size of the array.
Table of Contents
Sample Data
db.inventory.insertMany([ { item: "journal", qty: 25, tags: ["blank", "red"], book: { author:'xyz', price:50, location:['india', 'usa', 'nepal']} }, { item: "notebook", qty: 50, tags: ["red", "blank"], book: { author:'xyz', price:50, location:['india', 'usa']} }, { item: "paper", qty: 100, tags: ["red", "blank", "plain"], book: { author:'xyz', price:50, location:[]}}, { item: "planner", qty: 75, tags: ["blank", "red"], book: { author:'xyz', price:50, location:['india']} }, { item: "postcard", qty: 45, tags: ["blue"], book:{} } ]);
1. $size (to get exact length of array)
{ field: { $size: n } }; // n is any integer
The $size
operator matches any array with the number of elements specified by the argument.
$size
does not accept ranges of values.
Example
- Find elements where
tags
length is 1
db.inventory.find({tags:{$size:1}})
//output
[{ item: "postcard", qty: 45, tags: ["blue"], book:{} }]
2. Find elements where books location length is 1
db.inventory.find({books.loction:{$size:1}}
//output
[{ item: "planner", qty: 75, tags: ["blank", "red"], book: { author:'xyz', price:50, location:['india']} }]
2. $where
Use the $where
operator to pass either a string containing a JavaScript expression or a full JavaScript function to the query system
$where
evaluates JavaScript and cannot take advantage of indexes.
Example:
- Find elements where
tags
length is 1
db.inventory.find({tags:{$where:'this.tags.length == 1'}}
//output
[{ item: "postcard", qty: 45, tags: ["blue"], book:{} }]
2. Find elements where tags
length is greater or equal to 1
db.inventory.find({tags:{$where:'this.tags.length >= 1'}}
3. Find elements where books location length is 1
we cannot check this with the help of $where operator
Only apply the
$where
query operator to top-level documents. The$where
query operator will not work inside a nested document.
3. dot notation
MongoDB uses the dot notation to access the elements of an array and to access the fields of an embedded document.
"<array>.<index>"
Examples:
- Find elements where
tags
length greater than 0
db.inventory.find({tags.0:{$exists:true'}}
// It will search all elements whose tags has atleast one element
// array is zero base index
2. Find elements where books.location
length greater than 1
db.inventory.find({'book.location.1':{$exists:true'}}
// It will search all elements whose book.location has atleast two element.
4. $expr (3.6+)
{ $expr: { <expression> } }
Example:
- Find the document where
tags
length greater than 0
db.invantory.find({
$expr: {
$gt: [{ $size: { $ifNull: ["$tags", []] } }, 0]
}
})
2. Find elements where books.location
length greater than 1
db.invantory.find({
$expr: {
$gt: [{ $size: { $ifNull: ["$book.location", []] } }, 1]
}
})
// $ifNull: ["$book.location", []] this is used to avoid any error if book.location is null
5. Aggregation $facet operator:
db.inantory.aggregate([
{
$facet: {
"Total": [
{ $match: { 'tags.0': { $exists: true } } },
{ $count: "Total" }
]
}
},
{
$project: {
"Total": { "$arrayElemAt": ["$Total.Total", 0] },
}
}
])
- Find elements where
books.location
length greater than 1
db.inantory.aggregate([
{
$facet: {
"Total": [
{ $match: { 'books.location.0': { $exists: true } } },
{ $count: "Total" }
]
}
},
{
$project: {
"Total": { "$arrayElemAt": ["$Total.Total", 0] },
}
}
])