In this recipe, we will get our hands dirty with a bit of querying to select documents from the test data that we set up in our previous recipe, Creating test data. There is nothing extravagant in this recipe and someone who is well versed with the query language basics can skip this recipe. Others who aren't too comfortable with basic querying or those who want to get a small refresher can continue to read the next section of the recipe. Additionally, this recipe is intended to get a feel of the test data setup from the previous recipe.
To execute simple queries, we need to have a server up and running. A simple single node is what we need. Refer to the Installing single node MongoDB recipe from Chapter 1, Installing and Starting the Server for instructions on how to start the server. The data that we would be operating on needs to be imported in the database. The steps to import the data are given in the previous recipe, Creating test data. You also need to start the mongo shell and connect to the server running on the localhost. Once these prerequisites are complete, we are good to go.
> db.postalCodes.count()
postalCodes
collection as follows:> db.postalCodes.findOne()
> db.postalCodes.find().pretty()
Type "it" for more
. By typing "it"
, the mongo shell will iterate over the resulting cursor. Let's do a couple of things now; we will just display the city
, state
, and pincode
fields. Additionally, we want to display the documents numbered 91 to 100 in the collection. Let's see how we do this:> db.postalCodes.find({}, {_id:0, city:1, state:1, pincode:1}).skip(90).limit(10)
city
, state
, and the pincode
field:> db.postalCodes.find({state:'Gujarat'},{_id:0, city:1, state:1, pincode:1}).sort({city:1}).limit(10)
This recipe is pretty simple and allows us to get a feel for the test data that we set up in the previous recipe. Nevertheless, as with other recipes, I do owe you all some explanation for what we did here.
We first found the count of the documents in the collection using db.postalCodes.count()
and it should give us 39,732 documents. This should be in sync with the logs that we saw while importing the data in the postal codes collection. We next queried for one document from the collection using findOne
. This method returns the first document in the result set of the query. In absence of a query or sort order, as in this case, it will be the first document in the collection sorted by its natural order.
Next, we perform find
rather than findOne
. The difference between both of them is that the find
operation returns an iterator for the result set, which we can use to traverse through the results of the find operation, whereas findOne
returns a document. Adding a pretty method call to the find
operation will print the result in a pretty or formatted way.
We will now execute the following query on the mongo shell:
> db.postalCodes.find({}, {_id:0, city:1, state:1, pincode:1}).skip(90).limit(10)
Here, we pass two parameters to the find
method:
{}
, which is the query to select the documents, and, in this case, we ask mongo to select all the documents._id
field is present by default unless we explicitly say _id:0
. For all the other fields, we need to say <field_name>:1
or <field_name>:true
. The find portion with projections is the same as saying select field1
, field2 from table
in a relational world, and not specifying the fields to be selected in the find is saying select * from table
in a relational world.Moving on, we just need to look at what skip
and limit
do:
skip
function skips the given number of documents from the result set all the way up to the end documentlimit
function then limits the result to the given number of documentsLet's see what this all means with an example. By doing .skip(90).limit(10)
, we say that we want to skip the first 90
documents from the result set and start returning from the 91st document. The limit, however, says that we will be returning only 10
documents from the 91st document.
Now, there are some border conditions that we need to know here. What if skip is being provided with a value more than the total number of documents in the collection? Well, in this case, no documents will be returned. Additionally, if the number provided to the limit function is more than the actual number of documents remaining in the collection, then the number of documents returned will be the same as the remaining documents in the collection and no exception will be thrown in either cases.