Introduction to Mongoose Queries

In this article 👇

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.

You might also like...

Digital Ocean

The simplest cloud platform for developers & teams. Start with a $200 free credit.

Buy me a coffee ☕

If you enjoy reading my articles and want to help me out paying bills, please consider buying me a coffee ($5) or two ($10). I will be highly grateful to you ✌️

Enter the number of coffees below:

✨ Learn to build modern web applications using JavaScript and Spring Boot

I started this blog as a place to share everything I have learned in the last decade. I write about modern JavaScript, Node.js, Spring Boot, core Java, RESTful APIs, and all things web development.

The newsletter is sent every week and includes early access to clear, concise, and easy-to-follow tutorials, and other stuff I think you'd enjoy! No spam ever, unsubscribe at any time.