In the previous article, we already discussed how to perform basic types of search operations in MongoDB. Now, in this article, we will discuss advanced querying of the data in the MongoDB. We can perform any type of ad-hoc queries on the database to find a particular group of data. Also, we can use the range operator for the data query logic. In MongoDB, each query command returns a cursor which basically returns the batch of documents as we provide the conditions of search.
Cursors
When we use the find method in the MongoDB, then it always returns the result as a cursor. With the implementation of the cursor in our query, we can achieve great control over the output result which fetches from the database. We can manipulate the total number of results, can skip some numbers in the results, and sort the results with any combination using the cursor.
To define a cursor in the MongoDB shell, we need to query data on a document and then assign that result into a local variable (in MongoDB, the local variable can be defined by the “var” keyword).
var cursor = db.Employee.find()
The main advantage of defining the cursor is that we can analyze all the results at one time. Since we do not assign the data into a variable, MongoDB shell will automatically show the documents on the screen. This is normal behavior. But, if we store that result, then we can check the result and represent the output as we want. So, to iterate the data, we can use the next method on the cursor. If we want to check if either variable contains any data or not, then we need to use a hasNext command. Similarly, if we want to move to the next record then we can use the next() method.
Actually, when we call the find method, MongoDB shell does not communicate with the database for the data. MongoDB shell actually waits until we start to send the request for the result by sending the query. Now, when we execute the command cursor.hasNext() method, then MongoDB shell sends the query to the server. After it, shell fetches the first 100 results or 4 MB result (whichever is smaller size) at a single request so that with next call shell does the same steps to fetch next set of records. This process continues until the cursor is exhausted or all results have been returned to the query.
Limit, Skip & Sorts
In MongoDB, there are several commands that can be used to implement the cursor properly for fetching the data, including some customized operations like sort, skip etc. The below tables displays the list of commands which can be used for implementing the cursor in the MongoDB.
Operator | Descriptions | Example |
limit | This command is used to limit the number of records during find(). This command sets the upper limit of the records to be displayed. This means if we provide limit value as 5 and total records as per the condition as 4 then all 4 records will be returned by the query. | db.posts.find().limit(5)This command returns document list which returns up to 5 documents list |
skip | This command works similarly to limit. The only difference is that it will skip the number of records mentioned in the skip method and then return the result of the documents. | db.posts.find().skip(5)This command returns document list in which it will skip the first 5 records and then display the rest of the employees. |
sort | This command is used to display the fetch documents in a collection in a specified order. With this method, we can provide two parameters – one is a field name or object name which will be sorted and the second one is order – 1 for ascending and -1 for descending order. Sort command basically maintains the predefined sort order of the display data types - Minimum Value
- Null
- Numbers (integer, long, double)
- Strings
- Object/Document5s
- Array
- Binary data
- Object Id
- Boolean
- Date
- Timestamp
- Booking
- Date.
| db.posts.find().sort({“author”:1})This command returns document list with the ascending order of the system. |
Immortal Cursor
Actually, in MongoDB cursors are two types – one is the client-facing cursor and another is the server-facing cursor. So far we have only discussed the client-facing cursor. Now, we need to discuss something about the server-facing aspect of the cursor. In the server-side, each cursor takes memory and resource allocations. Once the cursor runs the results or the client sends a message to the server, then the database immediately frees the resources which it was using. By freeing these resources, the database can do the other operations. So, ultimately the cursor can be freed quickly from the server.
Actually, there are several conditions where a cursor can die. At first, when a cursor finishes its iteration through the matching of the records, it will clean itself. Another way is when a cursor goes out of focus on the client side, then the drivers send a signal to the database about the cursor that it can kill that cursor. Finally, event user does not retrieve all the records by executing all the iterations and the cursor still exists in the scope, then after 10 minutes of inactivity, that database cursor will automatically die. Also, if the client crashed, then MongoDB will not be left with thousands of open cursors. But sometimes, we might need a cursor which needs to last a long time. In that case, many MongoDB drivers have implemented a function called immortal. This cursor mainly tells the database not to timeout the cursor. If we do not specify the cursor timeout, then we need to fetch all data by using repetitive cursor iteration and then kill this cursor to make sure it gets closed.
Database Commands
Database command is another special type of query fetching from MongoDB. We already discussed insert, update, delete and find documents. This command can do everything like “Everything else” which can be done by using the server. Database commands do “everything else,” from administrative tasks like shutting down the server and cloning databases to counting documents in a collection and performing aggregations. Commands are mentioned throughout this text, as they are useful for data manipulation, administration, and monitoring. For example, dropping a collection is done via the "drop" database command,
- db.runCommand({
- "drop": "test"
- });
-
- {
-
- "nIndexesWas": 1,
- "msg": "indexes dropped for collection",
- "ns": "test.test",
- "ok": true
- }
In this section, we will take a closer look at the commands to see exactly what they are and how they’re implemented. We’ll also describe some of the most useful commands that are supported by MongoDB. You can see all the commands by running the db.listCommands() command.
Hope, this article will help you.