Mongoose models provide several functions for querying, updating, and deleting documents from a MongoDB collection. All of these functions return a Mongoose Query object.

const mongoose = require('mongoose')
const { Schema } = mongoose

const productSchema = new Schema({
  name: String,
  color: String,
  price: Number
})

const Product = mongoose.model('Product', productSchema)

const query = Product.findOne({ name: 'iPhone XL' })

// Execute query
const doc = await query

Executing queries

There are two ways to execute a Mongoose query. You can either pass in a callback function or use the then() method to execute the query as a promise.

When executing a query with a callback function, you need to pass your query filters as a JSON object:

Product.findOne({ name: 'iPhone XL' }, (err, doc) => {
  if (err) {
    console.log(`Error: ${err}`)
    return
  }

  console.log(doc)
})

Mongoose will execute the above query and pass the results to the callback function. If an error occurs executing the query, the err parameter will contain an error document, and the doc object will be null. If the query executes successfully, the err parameter will be null, and the doc will be populated with the results.

Mongoose queries are not native JavaScript promises. But they have then() and catch() methods to execute queries as a promise.

Product.findOne({ name: 'iPhone XL' })
  .then(doc => console.log(doc))
  .catch(err => console.log(`Error: ${err}`))

Finally, you can also use async-await syntax to execute a Mongoose query:

try {
  const doc = await Product.findOne({ name: 'iPhone XL' })
  console.log(doc)
} catch (err) {
  console.log(`Error: ${err}`)
}

Chaining

Instead of specifying query filters as a JSON object, you can also use Mongoose's query helpers to build up query filters using chaining syntax.

Let us rewrite the above query using Query helper functions:

const doc = await Product.find().where('name').equals('iPhone XL')

Here is another example that uses several helper functions to build a query:

const doc = await Product.find()
  .where('name')
  .in(['iPhone XL', 'Snap X'])
  .where('price')
  .gte(5.99)
  .lte(10)
  .limit(5)
  .sort({ name: 1 })
  .select('name price')

A complete list of all available Query helper functions can be found on Mongoose's API docs.

Streaming

You can call the Mongoose's Query.cursor() helper method to stream query results from a MongoDB collection. This method returns an instance of QueryCursor:

const cursor = Product.find().cursor()

for (let doc = await cursor.next(); doc != null; doc = await cursor.next()) {
  console.log(doc)
}

Iterating through a Mongoose query also creates a cursor, as shown below:

for await (const doc of Product.find()) {
  console.log(doc)
}

✌️ Like this article? Follow me on Twitter and LinkedIn. You can also subscribe to RSS Feed.