MongoDB find()

In MongoDB the db.collection.find() method selects documents in a collection or view and returns a cursor to the selected documents..

The collection part is the name of the collection or view to search.

You can use it to return all documents, just some, or just one document. You can also specify which fields should be returned.

It’s important to note that it doesn’t actually return the documents. It merely returns a cursor to the documents. Having said that, it’s easier to say that it “returns documents”, and it’s typically referred to in such a manner – including in this article 🙂

Return All Documents

Here’s an example to demonstrate.

db.pets.find()

Result:

{ "_id" : 1, "name" : "Wag", "type" : "Dog", "weight" : 20 }
{ "_id" : 2, "name" : "Bark", "type" : "Dog", "weight" : 10 }
{ "_id" : 3, "name" : "Meow", "type" : "Cat", "weight" : 7 }
{ "_id" : 4, "name" : "Scratch", "type" : "Cat", "weight" : 8 }
{ "_id" : 5, "name" : "Bruce", "type" : "Bat", "weight" : 3 }

Here, we use the find() method to return all documents from the pets collection. We know that this returns all documents because we didn’t provide any filtering criteria. In fact, we didn’t provide any arguments.

When called with no arguments, find() returns all documents from a collection and returns all fields for the documents.

Another way to do the above is like this:

db.pets.find({})

In this case we pass an empty document.

By adding to this empty document, we can start to filter the results.

Filter the Results

The actual syntax of find() goes like this:

db.collection.find(query, projection)

This means that you can pass a query as the first argument, and a projection as the second.

If you pass a query, it is used to filter the results. A query is a document that contains query operators. As we saw in the previous example, an empty document returns all documents.

Let’s narrow the results down to a subset of documents in the collection.

db.pets.find({"type":"Dog"})

Result:

{ "_id" : 1, "name" : "Wag", "type" : "Dog", "weight" : 20 }
{ "_id" : 2, "name" : "Bark", "type" : "Dog", "weight" : 10 }

This narrowed the results to just those documents that have a type field with a value of Dog.

In this case, we simply passed a document as the filtering criteria.

You can also use query operators. These allow you to apply more specific criteria to your query.

Example:

db.pets.find({"weight": { $lt: 10 }})

Result:

{ "_id" : 3, "name" : "Meow", "type" : "Cat", "weight" : 7 }
{ "_id" : 4, "name" : "Scratch", "type" : "Cat", "weight" : 8 }
{ "_id" : 5, "name" : "Bruce", "type" : "Bat", "weight" : 3 }

Embedded Documents

If you have documents that contain embedded documents, you can use the following methods to query data in the embedded documents.

  • Dot notation (e.g. field.nestedfield: <value>)
  • Nested form (e.g. { field: { nestedfield: <value> } }). Note that this option is only available from MongoDB 4.4.

Suppose we insert the following document.

db.pets.insertOne({
    "_id" : 6,
    "name" : "Fetch",
    "type" : "Dog",
    "specs" : {
        "height" : 400,
        "weight" : 15,
        "color" : "brown"
    }
})

We can use dot notation to query within the embedded document.

db.pets.find({ "specs.height": 400 })

Result:

{ "_id" : 6, "name" : "Fetch", "type" : "Dog", "specs" : { "height" : 400, "weight" : 15, "color" : "brown" } }

The following query returns the same document, except this time we reference the embedded document using nested form.

db.pets.find({ 
    "specs" : {
		"height" : 400,
		"weight" : 15,
		"color" : "brown"
	}
 })

Result:

{ "_id" : 6, "name" : "Fetch", "type" : "Dog", "specs" : { "height" : 400, "weight" : 15, "color" : "brown" } }

When using the nested form, the query must match whole embedded document exactly. For example, the following query doesn’t match:

db.pets.find({ 
    "specs" : {
		"height" : 400
	}
 })

Format the Results

The previous example’s result was returned in one line. You can use the cursor.pretty() method to configure the cursor to display the results in a more readable format.

To use the pretty() method, append it to the find() method.

Example:

db.pets.find({ "_id": 6 }).pretty()

Result:

{
	"_id" : 6,
	"name" : "Fetch",
	"type" : "Dog",
	"specs" : {
		"height" : 400,
		"weight" : 15,
		"color" : "brown"
	}
}

Arrays

You can reference data in arrays by referencing the array element by its index or by its value.

Suppose we insert the following document:

db.pets.insertOne({
    "_id" : 7,
    "name" : "Jake",
    "type" : "Dog",
    "awards" : [
        "Top Dog",
        "Best Dog",
        "Biggest Dog"
    ]
})

If we wanted to find all dogs with the Top Dog award, we could write the following query (which will return the above dog).

db.pets.find({ 
    "awards": "Top Dog"
}).pretty()

Result:

{
	"_id" : 7,
	"name" : "Jake",
	"type" : "Dog",
	"awards" : [
		"Top Dog",
		"Best Dog",
		"Biggest Dog"
	]
}

You can also specify the element index, like this:

db.pets.find({ 
    "awards.0": "Top Dog"
}).pretty()

Doing that requires that the specified value is at the specified index. Therefore, the following query does not return the same dog.

db.pets.find({ 
    "awards.1": "Top Dog"
}).pretty()

Note that arrays are zero-based, so an index of 0 specifies the first element, 1 specifies the second element, and so on.

Projections

By default, all document fields are returned when you use find(). But you can use projections to reduce the number of fields returned if required.

You may recall that the syntax for find() goes like this:

db.collection.find(query, projection)

Where query provides the filtering criteria (which we’ve done in the above examples), and projection is an optional projection that specifies which fields to return from any matching documents. Therefore, if we want to use a projection, we simply put it after the query.

When you use a projection, you can specify the fields to include, the fields to exclude, or both. To do this, list the name of the field and either a 1 (to include it) or 0 (to exclude it).

By now, our collection contains the following documents:

{ "_id" : 1, "name" : "Wag", "type" : "Dog", "weight" : 20 }
{ "_id" : 2, "name" : "Bark", "type" : "Dog", "weight" : 10 }
{ "_id" : 3, "name" : "Meow", "type" : "Cat", "weight" : 7 }
{ "_id" : 4, "name" : "Scratch", "type" : "Cat", "weight" : 8 }
{ "_id" : 5, "name" : "Bruce", "type" : "Bat", "weight" : 3 }
{ "_id" : 6, "name" : "Fetch", "type" : "Dog", "specs" : { "height" : 400, "weight" : 15, "color" : "brown" } }
{ "_id" : 7, "name" : "Jake", "type" : "Dog", "awards" : [ "Top Dog", "Best Dog", "Biggest Dog" ] }

Here’s an example of using a projection to specify the fields to include:

db.pets.find({}, { name: 1, type: 1 })

Result:

{ "_id" : 1, "name" : "Wag", "type" : "Dog" }
{ "_id" : 2, "name" : "Bark", "type" : "Dog" }
{ "_id" : 3, "name" : "Meow", "type" : "Cat" }
{ "_id" : 4, "name" : "Scratch", "type" : "Cat" }
{ "_id" : 5, "name" : "Bruce", "type" : "Bat" }
{ "_id" : 6, "name" : "Fetch", "type" : "Dog" }
{ "_id" : 7, "name" : "Jake", "type" : "Dog" }

Notice that the _id field is returned even though we didn’t include it in our projection. This field is an exception, and is included by default.

If you don’t want the _id field to be returned, you need to explicitly exclude it.

db.pets.find({}, { _id: 0, name: 1, type: 1 })

Result:

{ "name" : "Wag", "type" : "Dog" }
{ "name" : "Bark", "type" : "Dog" }
{ "name" : "Meow", "type" : "Cat" }
{ "name" : "Scratch", "type" : "Cat" }
{ "name" : "Bruce", "type" : "Bat" }
{ "name" : "Fetch", "type" : "Dog" }
{ "name" : "Jake", "type" : "Dog" }

Here’s another example, this time we only specify which fields to exclude.

db.pets.find({}, { _id: 0, weight: 0, specs: 0, awards: 0 })

Result:

{ "name" : "Wag", "type" : "Dog" }
{ "name" : "Bark", "type" : "Dog" }
{ "name" : "Meow", "type" : "Cat" }
{ "name" : "Scratch", "type" : "Cat" }
{ "name" : "Bruce", "type" : "Bat" }
{ "name" : "Fetch", "type" : "Dog" }
{ "name" : "Jake", "type" : "Dog" }

More Projections

There are various other things you can do with projections. For example, starting from MongDB 4.4 you can use aggregate expressions to specify the value of a projected field.

Example:

db.pets.find({}, { 
    "_id": 0,
    "n": "$name", 
    "t": "$type", 
    "w": "$weight" 
    })

Result:

{ "n" : "Wag", "t" : "Dog", "w" : 20 }
{ "n" : "Bark", "t" : "Dog", "w" : 10 }
{ "n" : "Meow", "t" : "Cat", "w" : 7 }
{ "n" : "Scratch", "t" : "Cat", "w" : 8 }
{ "n" : "Bruce", "t" : "Bat", "w" : 3 }
{ "n" : "Fetch", "t" : "Dog" }
{ "n" : "Jake", "t" : "Dog" }

Here, we renamed the field names. We did this by specifying a new name for each field as a string literal, the using the $fieldName syntax to output that fields value. The result is a bit like using aliases in SQL.

More Information

See the MongoDB documentation for more information.