Hour 6. Finding Documents in the MongoDB Collection from the MongoDB Shell


What You’ll Learn in This Hour:

Image Understanding the purpose of the Cursor object

Image Using the Cursor object to access documents in a collection

Image Finding single documents

Image Finding multiple documents

Image Using operators to find documents based on field values

Image Finding documents based on subdocuments fields


By far the most common operation on MongoDB databases is finding documents. This hour introduces you to accessing documents on a MongoDB server. The Collection object provides methods for finding documents on the server. You will get a chance to implement these methods to access documents.

Some of these methods return a Cursor object that represents a set of documents of the server. You will learn to use the Cursor object to access documents.

You will also learn how to use query operators to limit the results of database queries to specific documents. Query operators enable you to limit the documents based on field values, existences, size, and much more.

Understanding the Cursor Object

When you perform certain operations on the Collection object from the MongoDB shell client, the result comes back as a Cursor object. The Cursor object acts as a pointer that can be iterated on to access a set of objects in the database. For example, when you use find(), the actual documents are not returned; instead, a Cursor object returns. You can then use the Cursor object to read the items in the results.

Because the Cursor object can be iterated on, an index to the current location is kept internally. That way, you can read items one at a time. Keep in mind that some operations affect only the current item in the Cursor and increment the index. Other operations affect all items at the current index forward.

To give you an overall view of the Cursor object, Table 6.1 lists the basic methods that you can call on the Cursor object. These methods enable you to manipulate the Cursor object and control access to the actual documents that it represents.

Image
Image

TABLE 6.1 Basic Methods on the Cursor Object

Understanding Query Operators

Several of the operations you can perform with a Collection object to find and modify documents enable you to specify a query parameter. The query parameter simply defines a way to limit documents returned in a Cursor object to those that match specific criteria.

The query parameter is just a standard JavaScript object with special property names that the MongoDB shell and server understand. The properties of the query parameter are called operators because they operate on the data to determine whether a document should be included in the result set. These operators match the values of fields in the document against specific criteria.

For example, to find all documents with a count field value greater than 10 and name value equal to test, the query object would be

{count:{$gt:10}, name:'test'}

The operator $gt specifies documents with a count field larger than 10. Using the standard colon syntax of name:'test' is also an operator that specifies that the name field must equal test. Notice that the query object has multiple operators. You can include several different operators in the same query.

When specifying field names in a query object, you can use dot notation to specify subdocument fields. For example, consider the following object format:

{
  name:"test",
  stats: { height:74, eyes:'blue'}
}

You can query users that have blue eyes using the following query object:

{stats.eyes:'blue'}

Table 6.2 lists the more commonly used query operators.

Image
Image
Image

TABLE 6.2 query Operators That Define the Result Set Returned by and Operated on MongoDB Requests

Getting Documents from a Collection

One of the most common tasks you will be performing on data stored in a MongoDB is retrieving one or more documents. For example, consider product information for products displayed on a commercial website. The product information is stored once but retrieved many times.

Retrieval of data sounds fairly simple, but it can become quite complex as you add the need to filter, sort, limit, and aggregate the results. The entire next hour is devoted to the complexities of retrieving data.

The following sections introduce you to the basics of the find() and findOne() methods of the Collection object and show how to use them to access documents in a collection.

Consider the syntax for find() and findOne():

findOne(query, projection)
find(query, projection)

Both find() and findOne() accept a query object as the first parameter. The query object contains the query operators that will be matched against fields in the documents. The return set will contain documents that match the query. The projection parameter is an object that specifies the fields to include in the returned documents.

The difference between the find() and findOne() methods is that find() returns a Cursor object that represents the documents that match the query criteria. The findOne() method returns the first document that matches the query criteria.

Finding Specific Sets of Documents

Now that you know how to use the find() and findOne() methods to access documents in a collection, you will find yourself wanting to find specific documents. Limiting the results to specific documents provides several benefits, including these:

Image Less network traffic required

Image Less memory used on the client and server

Image Less processing on the client to find important data

To limit the resulting documents included in the find() method, you should apply a query object that limits the documents that will be returned in the Cursor. Table 6.2 lists the query operators that you can use to limit the Cursor results to a specific set of documents.

The following sections discuss using the query operators on the example words database to limit the find() result set in different ways.

Finding Documents Based on a Field Value

The most basic method of limiting the results is to specify a field value that must match in the query document. Only documents that contain the specified value in the specified field are returned.

For example, to get words that have a length of 5 from the words database, you would use a query similar to the following:

find({size: 5});

Similarly, to get the word there from the database, you would use the following:

find({word: "there"});

Finding Documents Based on an Array of Possible Values

You can use the $in operator to query based on array values contained for a specific field in the document. A good example of this using the words database is finding words that start with a, b, or c based on the first field in the document. The following shows an example of this:

find({first:{$in: ['a', 'b', 'c']}});

Finding Documents Based on Values Greater Than or Less Than

Another common query is to query based on a value that is greater than or less than an actual value. The $gt and $lt operators enable you to specify a field and a value that should be greater than or less than to include the document in the result set.

The following shows an example of finding documents based on a greater than value:

find({size:{$gt: 12}});

The following shows an example of finding documents based on a less than value:

find({size:{$lt: 12}});

Finding Documents Based on the Size of an Array Field

Another common query is finding documents that have an array field of a specific size. The $size operator enables you to use the array size in your queries.

For example, the following query finds words in which the letters array field is exactly 12 letters:

find({letters:{$size: 12}});

Similarly, the following query finds words in which the letters array field is greater than 10:

find({letters:{$size: {$gt: 10}}});

Finding Documents Based on Values in Subdocuments

You might also need to find documents based on the values contained in subdocuments. To do this, simply refer to the subdocument using the dot syntax. For example, in the words database, you can use the following query to access the vowels field of the stats subdocument in a word document:

{"stats.vowels":{$gt:6}}

Finding Documents Based on the Contents of an Array Field

Another useful query is the capability to find documents based on the contents of an array. The $all operator matches documents in which all elements in the query array are also found in the array field in the document.

For example, the following query on the words database finds words that contain all five of the vowels:

{letters:{$all: ['a','e','i','o','u']}}

Finding Documents Based on the Existence of a Field

Because MongoDB does not require a structured schema, sometimes some documents might include a field and others might not. The $exists operator if useful when dealing with documents that might or might not have a field. That way, you can limit the results to only documents that have or do not have the field.

For example, in the words database, words that do not have non-alphabetical characters do not have an otherChars field. The following query finds words with non-alphabet characters:

{otherChars: {$exists:true}}

Finding Documents Based on Fields in an Array of Subdocuments

A challenging query using the MongoDB document model is finding documents based on criteria of subdocuments contained in an array. In this case, the document has an array of subdocuments, and you want to query based on fields in the subdocument.

To query based on subdocuments, you use the $elemMatch operator. This operator enables you to specify a query to perform on each subdocument in the array.

The simplest way to illustrate $elemMatch is using the charsets subdocument array in the words database. The charsets field is an array of documents with the following structure:

{
  type: <string>,
  chars: <array>
}

The following query matches documents that have a charset subdocument with type="other" and the chars array with a size of 2:

{charsets:{$elemMatch: {$and: [{type: 'other'},{chars: {$size: 2}}]}}}

Summary

In this hour, you learned how to find documents in a collection on the MongoDB server using shell scripts. The find() method returns a Cursor object that represents the actual documents on the server. You learned how to use the Cursor object to retrieve the documents and access them in your shell scripts.

Methods that find documents enable you to specify a query object that contains query operators that define documents to include in the query. These query operators enable you to find specific sets of documents based on field values, existences, size, and much more.

Q&A

Q. Is there a way to query for null values on a field?

A. Not specifically. The different query operators handle a value of null in different ways. For example, if you specify a value of null in a direct field query such as {name: null}, then documents where name=null are returned—and so are documents that do not have a name field. Avoid trying to query by null; instead, do not include the null fields in the document, but use the $exists operator.

Q. Is it possible for MongoDB to return the same document more than once in a query if it matches multiple cases?

A. Yes. You can use the cursor.snapshot() method to traverse the index for the _id field and ensure that the same document is not included more than once. However, you cannot do this on sharded collections or with sort() and hint().

Workshop

The workshop consists of a set of questions and answers designed to solidify your understanding of the material covered in this hour. Try answering the questions before looking at the answers.

Quiz

1. True or false: The find() method returns an array of documents.

2. How do you tell how many documents are represented by a Cursor object?

3. Which query operator would you use to find documents that have a field value based on an array of possible values?

4. What does the query operator $size specify?

Quiz Answers

1. False. It returns a Cursor object.

2. Use the cursor.size() method.

3. $in

4. The number of elements in an array field.

Exercises

1. Extend the find_one.js example to use findOne() and specify a query in which the word field equals "there"—for example, {word: "there"}. Then display the resulting document.

2. Extend the find_specific.js example to include a query that finds words in which the first letter is l and the last letter is t that have a size of 4. Hint: You need to use the $and operator first.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
52.14.134.113