Definition
In MongoDB, the $size operator is used in queries to match documents based on the number of elements in a specified array field. It allows you to find documents where the size of the array matches a specified value. MongoDB is popular because its easy and efficient operators speed up the process and optimize results.
To retrieve the document, you can use the below
syntax:
db.collection.find({ arrayField: { $size: sizeValue } })
For example:
db.collection.find( { field: { $size: 2 } } );
The above line of code will retrieve all documents in the collection where the field is an array with 2 elements.
This blog highlights the use of the $size operator, along with simple examples and use cases.
Purpose:
“In MongoDB, the $size operator allows you to filter documents based on the size of a specified array field. It retrieves documents where the size of the array matches a specified value. The $size operator is part of the query language in MongoDB and can be combined with other query operators.”
Table of Contents
Key Takeaways
- The $size operator will match any array with the argument’s number of elements.
- You must use a counter field in MongoDB and increment it when adding elements to a field rather than relying on $size with ranges.
- You can use the $size operator with other MongoDB methods, like find(), findOne(), etc, to filter documents as per the elements inside an array.
What is the $size Operator in MongoDB?
With the help of the “$size” operator, you can easily filter the documents based on the particular array of a specific size. The $size works well with arrays and accepts only numeric values as a parameter. This simple guide will explain how you can work around the $size operator.
For example:
db.collection.find( { field: { $size: 3 } } );
The above line of code will retrieve all documents in the collection where the field is an array with 3 elements.
Note: The $size does not support ranges or inequalities. It only filters documents based on an exact match of array size. If you need to query for arrays with a size greater than or less than a specific value, you might need to use alternative approaches or consider restructuring your data.
Working of $size Operator in MongoDB
We have simply explained MongoDB’s $size operator in the steps below.
- It will match an array field with the size provided by the user.
- It will fetch the documents containing the fields that fulfill the above condition.
The $size operator is used within the find method to fetch documents based on the size of an array field. The basic syntax is.
db.collection.find({ arrayField: { $size: sizeValue } })
Here, arrayField is the name of the array field, and sizeValue is the desired array size.
How do you use the $size operator in MongoDB?
Let’s review examples of using the $size operator in MongoDB, explanations, and expected outputs.
In the below example, we are querying the array fields using the db.collection.find()method. Here, we are using the inventory collection. To populate this collection, run the below command.
db.inventory.insertMany([
{ item: "doc", qty: 25, tags: ["black", "red"], dim_cm: [ 14, 21 ] },
{ item: "book", qty: 10, tags: ["red", "black"], dim_cm: [ 14, 21 ] },
{ item: "planner", qty: 15, tags: ["black", "red"], dim_cm: [ 22.85, 30 ] },
{ item: "card", qty: 45, tags: ["green"], dim_cm: [ 10, 15.25 ] }
]);
Now, we will run several operations, as shown below.
Example 1- Match an Array
The below example will look for the documents where the field tags value is an array with exactly two elements, “red” and “black”, in the specified order.
db.inventory.find( { tags: ["red", "black"] } )
Output:
This output represents the document in the inventory collection where the field tags have exactly two elements, “red” and “black,” in the specified order. In this case, it matches the document with the item “doc” in the inventory.
Use the $ all operator to find an array containing the elements “red” and “black”, regardless of their order or the other elements in the array.
db.inventory.find( { tags: { $all: ["red", "black"] } } )
Output :
Output:
{ "item" : "doc", "qty" : 25, "tags" : [ "black", "red" ], "dim_cm" : [ 14, 21 ] }
{ "item" : "book", "qty" : 10, "tags" : [ "red", "black" ], "dim_cm" : [ 14, 21 ] }
{ "item" : "planner", "qty" : 15, "tags" : [ "black", "red" ], "dim_cm" : [ 22.85, 30 ] }
This output includes all documents in the inventory collection where the “tags” field contains both “red” and “black”.
Example 2- Querying an Array for a specific Element
You can query if the given array field has at least one element with the provided data using the filter { <field>:<value> } where <value> refers to the element value.
The below example will query all docs where the tag is an array containing the string element “red”.
db.inventory.find( { tags: "red" } )
Output:
Output:
{ "item" : "doc", "qty" : 25, "tags" : [ "black", "red" ], "dim_cm" : [ 14, 21 ] }
{ "item" : "book", "qty" : 10, "tags" : [ "red", "black" ], "dim_cm" : [ 14, 21 ] }
This output includes all documents in the inventory collection where the “tags” field contains the element “red”.
Example 3- Specify Multiple Conditions for Array Elements
In case of multiple conditions, specify the query such that either a single array element fulfills the conditions or any combination of array elements meets the conditions.
db.inventory.find( { dim_cm: { $gt: 15, $lt: 20 } } )
Output:
Output:
{ "item" : "doc", "qty" : 25, "tags" : [ "black", "red" ], "dim_cm" : [ 14, 21 ] }
This document has “dim_cm” values within the specified range (greater than 15 and less than 20).
Advanced Techniques with $size
Now, we will explain the query operations on an array of nested documents using the db.collection.find() method. We will use the ‘inventory’ collection. To populate the ‘inventory’ collection, execute the below command.
db.inventory.insertMany( [
{ item: "doc", instock: [ { workshop: "A", qty: 5 }, { workshop: "C", qty: 15 } ] },
{ item: "book", instock: [ { workshop: "C", qty: 5 } ] },
{ item: "b_planner", instock: [ { workshop: "A", qty: 40 }, { workshop: "B", qty: 5 } ] },
{ item: "card", instock: [ { workshop: "B", qty: 15 }, { workshop: "C", qty: 35 } ] }
]);
Example 1- Query for a Document Nested in an Array
The below command will select all documents with the element in the instock array that matches the specified document.
db.inventory.find( { "instock": { workshop: "A", qty: 5 } } )
Output:
There are no documents in the inventory collection where the “instock” array contains a document with the workshop “A” and qty “5,” exactly as specified in the query.
Exact matches for entire embedded or nested documents necessitate a precise match with the specified document, including the order of fields. For instance, the subsequent query finds no documents in the ‘inventory’ collection.
db.inventory.find({ "instock": { $elemMatch: { qty: 5, workshop: "A" } } })
Output:
This document has an “instock” array that contains a document with “qty: 5” and “workshop: A”.
Example 2- Specify a Condition on a Field in an Array of Documents
You can use the dot notation to set query conditions for a field within a document at a specific index or position in the array. The array follows zero-based indexing.
In the example below, all documents are selected where the ‘instock’ array’s first element contains the field ‘qty’ with a value less than or equal to 25.
db.inventory.find( { 'instock.0.qty': { $lte: 25 } } )
Output:
This output includes the documents in the “inventory” collection where the quantity (qty) of the first element in the “instock” array is less than or equal to 25.
Example 3- Match an Embedded/Nested Document
We will explain the query operations on embedded/nested documents using the db.collection.find() method. We will use the inventory collection. We are adding details to the collection using the command below.
db.inventory.insertMany( [
{ item: "doc", qty: 65, size: { h: 84, w: 11, unit: "in" }, status: "C" },
{ item: "book", qty: 40, size: { h: 9.5, w: 10, unit: "cn" }, status: "A" },
]);
To define an equality condition for a field that is an embedded or nested document, employ the query filter document { <field>: <value> }, where <value> represents the document to be matched.
For example, the subsequent query retrieves all documents where the field ‘size’ equals the document { h: 84, w: 11, unit: “in” }.
db.inventory.find( { size: { h: 84, w: 11, unit: "in" } } )
Output:
{ "item" : "doc", "qty" : 65, "size" : { "h" : 84, "w" : 11, "unit" : "in" }, "status" : "C" }
This document matches the query because its “size” field exactly matches the specified embedded document.
Exact matches for an entire embedded document necessitate a precise match with the specified <value> document, including maintaining the order of fields.
Best Practices for Using $size
To get better results, ensure that you follow the below best practices.
- Ensure you use $size when you require an exact match for an array’s size.
- The $size operator is designed to find documents with arrays of a specific length.
- The $size does not support ranges or inequalities. If your query involves finding documents with array sizes within a range, you must go for alternative approaches, such as using a counter field.
- Consider performance implications when using $size, especially on large collections. The operator may lead to less efficient queries, particularly if a collection scan is required.
- Understand that using $size might limit the effectiveness of indexes. In some instances, MongoDB may need to perform a collection scan instead of utilizing an index, impacting query performance.
- When searching for documents with non-existent or empty arrays, consider using the $exists operator instead. Using $size for this purpose may be less efficient.
- Assess your data schema and requirements before relying heavily on $size. Depending on your use case, it might be more efficient to structure your data differently or use additional fields to store relevant information.
Conclusion
The $size operator in MongoDB is a valuable tool for querying documents based on the exact size of an array field. Its primary strength is providing a straightforward way to find documents with arrays of specific lengths.
However, users should be aware of its limitations, such as the inability to handle ranges or inequalities, potential performance implications, and considerations regarding index usage. While $size has its place in specific scenarios, developers are encouraged to assess their data schema and query requirements critically, exploring alternative approaches when necessary for more efficient and flexible solutions.
FAQs
Q1. Is $size efficient for large datasets?
Answer: Consider efficiency with $size on large datasets, as it may impact performance, particularly if a collection scan is needed. Explore alternatives for better efficiency.
Q2. Can $size be used with arrays containing nested documents?
Answer: Yes, $size works with arrays of nested documents. Ensure your query aligns with the exact structure of the nested documents, including field order.
Q3. How does indexing impact $size query performance?
Answer: Indexing may affect the performance of $size queries. MongoDB might opt for a collection scan instead of an index, influencing overall query efficiency. Assess the impact of indexing on your specific use case.
Q4. What are alternatives to $size for flexible array queries?
Answer: Consider alternatives like maintaining a counter field or using $expr with aggregation stages for more flexibility and efficiency, especially when dealing with complex array size conditions.
Recommended Articles
We hope this EDUCBA information on “MongoDB $size” benefited you. You can view EDUCBA’s recommended articles for more information.