Query Documents
In MongoDB, the db.collection.find() method retrieves documents from a collection. The db.collection.find() method returns a cursor to the retrieved documents. The examples explains read operations using the db.collection.find() method in the mongo shell. The db.collection.findOne() method also performs a read operation to return a single document. Internally, the db.collection.findOne() method is the db.collection.find() method with a limit of 1.
Select All Documents in a Collection – An empty query document ({}) selects all documents in the collection
db.inventory.find( {} )
Not specifying a query document to the find() is equivalent to specifying an empty query document. Therefore the following operation is equivalent to the previous operation:
db.inventory.find()
Equality Condition – To specify equality condition, use the query document { <field>: <value> } to select all documents that contain the <field> with the specified <value>. The following example retrieves from the inventory collection all documents where the type field has the value snacks, as
db.inventory.find( { type: “snacks” } )
Using Query Operators – A query document can use the query operators to specify conditions in a MongoDB query. The following example selects all documents in the inventory collection where the value of the type field is either ‘food’ or ‘snacks’:
db.inventory.find( { type: { $in: [ ‘food’, ‘snacks’ ] } } )
Although you can express this query using the $or operator, use the $in operator rather than the $or operator when performing equality checks on the same field.
AND Conditions – A compound query can specify conditions for more than one field in the collection’s documents. Implicitly, a logical AND conjunction connects the clauses of a compound query so that the query selects the documents in the collection that match all the conditions. In the following example, the query document specifies an equality match on the field food and a less than ($lt) comparison match on the field price:
db.inventory.find( { type: ‘food’, price: { $lt: 9.95 } } )
This query selects all documents where the type field has the value ‘food’ and the value of the price field is less than 9.95.
OR Conditions – Using the $or operator, you can specify a compound query that joins each clause with a logical OR conjunction so that the query selects the documents in the collection that match at least one condition. In the following example, the query document selects all documents in the collection where the field qty has a value greater than ($gt) 100 or the value of the price field is less than ($lt) 9.95:
db.inventory.find(
{ $or: [
{ qty: { $gt: 100 } },
{ price: { $lt: 9.95 } }
]
} )
Specify AND as well as OR Conditions – With additional clauses, you can specify precise conditions for matching documents. In the following example, the compound query document selects all documents in the collection where the value of the type field is ‘food’ and either the qty has a value greater than ($gt) 100 or the value of the price field is less than ($lt) 9.95, as
db.inventory.find( { type: ‘food’, $or: [ { qty: { $gt: 100 } },
{ price: { $lt: 9.95 } } ]
} )
Subdocuments Query – When the field holds an embedded document (i.e. subdocument), you can either specify the entire subdocument as the value of a field, or “reach into” the subdocument using dot notation, to specify values for individual fields in the subdocument:
Exact Match on Subdocument – To specify an equality match on the whole subdocument, use the query document { <field>: <value> } where <value> is the subdocument to match. Equality matches on a subdocument require that the subdocument field match exactly the specified <value>, including the field order. In the following example, the query matches all documents where the value of the field producer is a subdocument that contains only the field company with the value ‘ABC123’ and the field address with the value ‘123 Street’, in the exact order, as
db.inventory.find(
{ producer: { company: ‘ABC123’,
address: ‘123 Street’
}
} )
Equality Match on Fields within Subdocument – Equality matches for specific fields within subdocuments select the documents in the collection when the field in the subdocument contains a field that matches the specified value. In the following example, the query uses the dot notation to match all documents where the value of the field producer is a subdocument that contains a field company with the value ‘ABC123’ and may contain other fields:
db.inventory.find( { ‘producer.company’: ‘ABC123’ } )
Arrays Query – When the field holds an array, you can query for an exact array match or for specific values in the array. If the array holds sub-documents, you can query for specific fields within the sub-documents using dot notation:
Exact Match on an Array – To specify equality match on an array, use the query document { <field>: <value> } where <value> is the array to match. Equality matches on the array require that the array field match exactly the specified <value>, including the element order. In the following example, the query matches all documents where the value of the field tags is an array that holds exactly three elements, ‘fruit’, ‘food’, and ‘citrus’, in this order:
db.inventory.find( { tags: [ ‘fruit’, ‘food’, ‘citrus’ ] } )
Match an Array Element – Equality matches can specify a single element in the array to match. These specifications match if the array contains at least one element with the specified value. In the following example, the query matches all documents where the value of the field tags is an array that contains ‘fruit’ as one of its elements:
db.inventory.find( { tags: ‘fruit’ } )
Match a Specific Element of an Array – Equality matches can specify equality matches for an element at a particular index or position of the array. In the following example, the query uses the dot notation to match all documents where the value of the tags field is an array whose first element equals ‘fruit’:
db.inventory.find( { ‘tags.0’ : ‘fruit’ } )
Match a Field in the Subdocument Using the Array Index – If you know the array index of the subdocument, you can specify the document using the subdocument’s position.
The following example selects all documents where the memos contains an array whose first element (i.e. index is 0) is a subdocument with the field by with the value ‘shipping’:
db.inventory.find( { ‘memos.0.by’: ‘shipping’ } )
Match a Field Without Specifying Array Index – If you do not know the index position of the subdocument, concatenate the name of the field that contains the array, with a dot (.) and the name of the field in the subdocument. The following example selects all documents where the memos field contains an array that contains at least one subdocument with the field by with the value ‘shipping’:
db.inventory.find( { ‘memos.by’: ‘shipping’ } )
Match Multiple Fields – To match by multiple fields in the subdocument, you can use either dot notation or the $elemMatch operator. The following example uses dot notation to query for documents where the value of the memos field is an array that has at least one subdocument that contains the field memo equal to ‘on time’ and the field by equal to ‘shipping’:
db.inventory.find(
{
‘memos.memo’: ‘on time’,
‘memos.by’: ‘shipping’
}
)
The following example uses $elemMatch to query for documents where the value of the memos field is an array that has at least one subdocument that contains the field memo equal to ‘on time’ and the field by equal to ‘shipping’:
db.inventory.find( {
memos: {
$elemMatch: {
memo : ‘on time’,
by: ‘shipping’
}
}
}
)
Limit Fields to Return from a Query – The projection specification limits the fields to return for all matching documents. The projection takes the form of a document with a list of fields for inclusion or exclusion from the result set. You can either specify the fields to include (e.g. { field: 1 }) or specify the fields to exclude (e.g. { field: 0 }).
The _id field is, by default, included in the result set. To exclude the _id field from the result set, you need to specify in the projection document the exclusion of the _id field (i.e. { _id: 0 }). You cannot combine inclusion and exclusion semantics in a single projection with the exception of the _id field.
Return All Fields in Matching Documents – If you specify no projection, the find() method returns all fields of all documents that match the query.
db.inventory.find( { type: ‘food’ } )
This operation will return all documents in the inventory collection where the value of the type field is ‘food’. The returned documents contain all its fields.
Return the Specified Fields and the _id Field Only – A projection can explicitly include several fields. In the following operation, find() method returns all documents that match the query. In the result set, only the item and qty fields and, by default, the _id field return in the matching documents.
db.inventory.find( { type: ‘food’ }, { item: 1, qty: 1 } )
Return Specified Fields Only – You can remove the _id field from the results by specifying its exclusion in the projection, as in the following example
db.inventory.find( { type: ‘food’ }, { item: 1, qty: 1, _id:0 } )
This operation returns all documents that match the query. In the result set, only the item and qty fields return in the matching documents.
Return All But the Excluded Field – To exclude a single field or group of fields you can use a projection in the following form
db.inventory.find( { type: ‘food’ }, { type:0 } )
This operation returns all documents where the value of the type field is food. In the result set, the type field does not return in the matching documents.
With the exception of the _id field you cannot combine inclusion and exclusion statements in projection documents.
Projection for Array Fields – The $elemMatch and $slice projection operators are the only way to project portions of an array.
MongoDB does not support projections of portions of arrays except when using the $elemMatch and $slice projection operators.
Query Optimization – Indexes improve the efficiency of read operations by reducing the amount of data that query operations need to process. This simplifies the work associated with fulfilling queries within MongoDB.
Create an Index to Support Read Operations – If your application queries a collection on a particular field or fields, then an index on the queried field or fields can prevent the query from scanning the whole collection to find and return the query results. An application queries the inventory collection on the type field. The value of the type field is user-driven.
var typeValue = <someUserInput>;
db.inventory.find( { type: typeValue } );
To improve the performance of this query, add an ascending, or a descending, index to the inventory collection on the type field. In the mongo shell, you can create indexes using the db.collection.ensureIndex() method:
db.inventory.ensureIndex( { type: 1 } )
This index can prevent the above query on type from scanning the whole collection to return the results. In addition to optimizing read operations, indexes can support sort operations and allow for a more efficient storage utilization. For single-field indexes, the selection between ascending and descending order is immaterial. For compound indexes, the selection is important.
Query Selectivity – Some query operations are not selective. These operations cannot use indexes effectively or cannot use indexes at all. The inequality operators $nin and $ne are not very selective, as they often match a large portion of the index. As a result, in most cases, a $nin or $ne query with an index may perform no better than a $nin or $ne query that must scan all documents in a collection.
Queries that specify regular expressions, with inline JavaScript regular expressions or $regex operator expressions, cannot use an index with one exception. Queries that specify regular expression with anchors at the beginning of a string can use an index.
Covering a Query – An index covers a query, a covered query, when:
- all the fields in the query are part of that index, and
- all the fields returned in the documents that match the query are in the same index.
For these queries, MongoDB does not need to inspect documents outside of the index. This is often more efficient than inspecting entire documents. Given a collection inventory with the
following index on the type and item fields
{ type: 1, item: 1 }
This index will cover following query on the type and item fields, which returns only the item field
db.inventory.find( { type: “food”, item:/^c/ },
{ item: 1, _id: 0 } )
However, index will not cover the following query, which returns the item field and the _id field:
db.inventory.find( { type: “food”, item:/^c/ },
{ item: 1 } )
Query Plans – The MongoDB query optimizer processes queries and chooses the most efficient query plan for a query given the available indexes. The query system then uses this query plan each time the query runs. The query optimizer occasionally reevaluates query plans as the content of the collection changes to ensure optimal query plans. You can use the explain() method to view statistics about the query plan for a given query. This information can help as you develop indexing strategies.
Query Optimization – To create a new query plan, the query optimizer:
- runs the query against several candidate indexes in parallel.
- records the matches in a common results buffer or buffers.
- If the candidate plans include only ordered query plans, there is a single common results buffer.
- If the candidate plans include only unordered query plans, there is a single common results buffer.
- If the candidate plans include both ordered query plans and unordered query plans, there are two common results buffers, one for the ordered plans and the other for the unordered plans.
- If an index returns a result already returned by another index, the optimizer skips the duplicate match. In the case of the two buffers, both buffers are de-duped.
- stops the testing of candidate plans and selects an index when one of the following events occur
- An unordered query plan has returned all the matching results; or
- An ordered query plan has returned all the matching results; or
- An ordered query plan has returned a threshold number of matching results:
- Version 2.0: Threshold is the query batch size. The default batch size is 101.
- Version 2.2: Threshold is 101.
The selected index becomes the index specified in the query plan; future iterations of this query or queries with the same query pattern will use this index. Query pattern refers to query select conditions that differ only in the values, as in the following two queries with the same query pattern:
db.inventory.find( { type: ‘food’ } )
db.inventory.find( { type: ‘utensil’ } )
Query Plan Revision – As collections change over time, the query optimizer deletes the query plan and re-evaluates after any of the following events:
- The collection receives 1,000 write operations.
- The reIndex rebuilds the index.
- You add or drop an index.
- The mongod process restarts.
Apply for MongoDB Certification Now!!
https://www.vskills.in/certification/databases/mongodb-server-administrator