Read Documents: Part 1

Learn and practice the find and findOne commands to read documents, and see how to use the $eq operator in the filter query.

Find methods

There are two methods to find documents from a collection:

  1. findOne method

    db.<collection-name>.findOne(<filter query>, <projection>)
    
  2. find method

    db.<collection-name>.find(<filter query>, <projection>)
    

Both methods have the same input parameters.

The findOne method returns only one document, whereas the find method returns an array of documents. Both functions work without any arguments but running find on a collection with a large number of records can cause a memory error.

Terminal 1
Terminal
Loading...

Filter query

A filter query is an object that defines the criteria to filter documents of a collection. Below is the list of operators that can perform a search against a collection of documents:

  • Comparison operators
  • Logical operators
  • Element operators
  • Evaluation operators
  • Geospatial operators
  • Array operators
  • Bitwise operators
  • Projection operators
  • Miscellaneous operators

There are insert or update commands in every operator explanation. We can use them in terminals to practice operators. The _id field value will be different from what has been displayed in the outputs in examples.

Comparison operators

Comparison operators consist of operators that compare two values.

$eq: Equal to operator (=)

Below are the commands of the $eq operator:

  1. First syntax

    { <field>: <value> }
    
  2. Second syntax

    { <field>: { $eq: <value> } }
    

If the value is a regular expression, only the second syntax will work.

Let’s insert three tasks.

Press + to interact
db.tasks.insertMany([{
name: "Learn MongoDB Topic 1",
date: new Date("2020-07-21T11:41:29.383Z"),
priority: 1,
num: [1, 2],
status: "pending",
user: "onkar",
assignee: "onkar"
}, {
name: "Learn MongoDB Topic 2",
date: new Date("2020-07-21T11:41:29.383Z"),
priority: 1,
num: [1, 3],
status: "pending",
user: "onkar",
assignee: "onkar"
}, {
name: "Learn MongoDB Topic 3",
date: new Date("2020-07-21T11:41:29.383Z"),
priority: 1,
num: [1, 4],
status: "completed",
user: "onkar",
assignee: "onkar"
}]);

Below is a query to find tasks that have status: “pending”.

db.tasks.find({
    status: "pending",
});

This query returns the below output.

[
  {
    _id: ObjectId("60f807e9b307d94301b9cb93"),
    name: 'Learn MongoDB Topic 1',
    date: ISODate("2020-07-21T11:41:29.383Z"),
    priority: 1,
    num: [1, 2],
    status: 'pending',
    user: 'onkar',
    assignee: 'onkar'
  },
  {
    _id: ObjectId("60f807e9b307d94301b9cb94"),
    name: 'Learn MongoDB Topic 2',
    date: ISODate("2020-07-21T11:41:29.383Z"),
    priority: 2,
    num: [1, 3],
    status: 'pending',
    user: 'onkar',
    assignee: 'onkar'
  }
]
Using $eq operator on array field

If the specified value is an array, MongoDB matches documents where the field exactly matches the array.

Below is a query to perform matching on the array field.

db.tasks.find({
    num: [1, 3],
});

This query returns the document with Learn MongoDB Topic 2, as it has the num field value 1 and 3.

Terminal 1
Terminal
Loading...
Matching a Regular Expression

The document field value should be the type of regular expression to match with a regular expression using the $eq operator.

Below is an example of a $eq matching regular expression.

db.tasks.find({ 
    status: { 
        $eq: new RegExp("pending", "ig")
    } 
});

This query doesn’t return anything, because the status field stores a string instead of a regular expression.

Matching a field in Embedded Document

When applying any operator on the embedded document, we make sure to build a path with a dot(.) separator. For example, we set the path to assignee.username in order to apply the $eq operator on the username property of assignee in the task.

The filter doesn’t work on embedded documents without the dot separator.

Example 1

We’ll insert tasks to build a query in the embedded document.

Press + to interact
db.tasks.insertMany([
{
name: 'Task 1',
assignee: {
username: 'user_a',
},
},
{
name: 'Task 2',
assignee: {
username: 'user_b',
},
}
]);

Below is a query to perform a comparison on the username field.

db.tasks.find({
    'assignee.username': { $eq: 'user_a' },
})

This query returns the below output.

[
  {
    _id: ObjectId("60f97e28ac3c9ea06c0506a3"),
    name: 'Task 1',
    assignee: { username: 'user_a' }
  }
]

We can see that the document with username user_b is not returned, as we performed a query for user_a.

Example 2

Next, we’ll insert tasks to build a query on an array field with embedded documents as its value.

Press + to interact
db.tasks.insertMany([
{
name: 'Task 1',
categories: [{
key: 'category_a',
}, {
key: 'category_b',
}]
},
{
name: 'Task 2',
categories: [{
key: 'category_c',
}, {
key: 'category_d',
}]
}
]);

Below is a query to perform a comparison on the category key.

db.tasks.find({
    'categories.key': 'category_a',
})

This query returns the below output.

[
  {
    _id: ObjectId("60f98039ac3c9ea06c0506a5"),
    name: 'Task 1',
    categories: [
        {
            key: 'category_a'
        },
        {
            key: 'category_b'
        }
    ]
  }
]

Notice that the document with category key category_c is not returned, as we performed a query for the category_a.

When we search for an array of documents using the $eq operation, the query returns documents only if any of the child document matches that respective field value.

The $eq operation can be used on multiple child documents at multiple levels.

We won’t repeat embedded document explanations for other operators. They are applied in the same way.

Terminal 1
Terminal
Loading...

Q&A

Here are some questions to test your understanding of this lesson.

Question 1

What is the use of the $eq operator?

Show Answer
Question 2

What’s the use of the dot separator?

Show Answer