mongodb
mongoose
raw operations
database
javascript

How to do raw mongodb operations in mongoose?

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

Mongoose is a popular ODM (Object Document Mapper) library for MongoDB in Node.js, offering a structured way to interact with MongoDB databases and facilitating schema design, data validation, and business logic hooks. However, sometimes you may need the flexibility and power of raw MongoDB operations. Fortunately, Mongoose provides a way to perform these operations directly on collections while maintaining the benefits of its connection and model management.

Understanding Mongoose and Raw MongoDB Operations

While Mongoose excels at abstracting MongoDB's native syntax, it can be advantageous to perform raw operations for:

  1. Performance: When executing complex operations that would benefit from the raw power of MongoDB.
  2. Flexibility: When a particular MongoDB feature isn't supported directly by Mongoose or when requiring fine-grained control over the query.
  3. Compatibility: When using plugins or integrations that necessitate raw commands.

Creating a Mongoose Model

Before diving into raw operations, you should have a working Mongoose model to interact with.

javascript
1const mongoose = require('mongoose');
2
3// Define a schema
4const userSchema = new mongoose.Schema({
5  name: String,
6  age: Number,
7  email: String
8});
9
10// Create a model
11const User = mongoose.model('User', userSchema);

Accessing the Native MongoDB Collection

Mongoose models have an internal method called collection, which provides direct access to the MongoDB native collection methods.

javascript
1User.collection.find({}).toArray((err, docs) => {
2  if (err) throw err;
3  console.log("Raw MongoDB Results:", docs);
4});

Performing Raw Operations

1. Find Documents

To find documents, you can use the find method provided by the collection object.

javascript
1User.collection.find({ age: { $gt: 20 } }).toArray((err, docs) => {
2  if (err) throw err;
3  console.log("Users older than 20:", docs);
4});

2. Insert Documents

Inserting documents can be performed using the insertOne or insertMany methods.

javascript
1// Insert a single document
2User.collection.insertOne({ name: "Alice", age: 30, email: "[email protected]" }, (err, result) => {
3  if (err) throw err;
4  console.log("Inserted Document ID:", result.insertedId);
5});
6
7// Insert multiple documents
8User.collection.insertMany([{ name: "Bob", age: 25 }, { name: "Charlie", age: 22 }], (err, result) => {
9  if (err) throw err;
10  console.log("Inserted Document IDs:", result.insertedIds);
11});

3. Update Documents

For updates, you can leverage updateOne or updateMany.

javascript
1// Update a single document
2User.collection.updateOne({ name: "Alice" }, { $set: { age: 31 } }, (err, result) => {
3  if (err) throw err;
4  console.log("Matched Documents:", result.matchedCount);
5  console.log("Modified Documents:", result.modifiedCount);
6});
7
8// Update multiple documents
9User.collection.updateMany({ age: { $lt: 25 } }, { $set: { isActive: true } }, (err, result) => {
10  if (err) throw err;
11  console.log("Matched Documents:", result.matchedCount);
12  console.log("Modified Documents:", result.modifiedCount);
13});

4. Delete Documents

Documents can be removed using deleteOne or deleteMany.

javascript
1// Delete a single document
2User.collection.deleteOne({ name: "Bob" }, (err, result) => {
3  if (err) throw err;
4  console.log("Deleted Document Count:", result.deletedCount);
5});
6
7// Delete multiple documents
8User.collection.deleteMany({ age: { $gte: 30 } }, (err, result) => {
9  if (err) throw err;
10  console.log("Deleted Document Count:", result.deletedCount);
11});

5. Aggregations

MongoDB's powerful aggregation pipeline can be accessed similarly.

javascript
1User.collection.aggregate([
2  { $match: { age: { $gt: 20 } } },
3  { $group: { _id: "$isActive", averageAge: { $avg: "$age" } } }
4]).toArray((err, results) => {
5  if (err) throw err;
6  console.log("Aggregation Results:", results);
7});

A Summary of Operations in Mongoose

Here's a quick summary table of typical raw operations you might perform using Mongoose's collection:

OperationMethodDescription
FindfindRetrieves documents based on a filter.
InsertinsertOne, insertManyAdds new documents to the collection.
UpdateupdateOne, updateManyModifies existing documents based on a filter.
DeletedeleteOne, deleteManyRemoves documents matching a filter.
AggregateaggregatePerforms complex data processing and transformations.

Conclusion

While Mongoose provides a rich API for interacting with MongoDB using its schema-based approach, there are scenarios where raw MongoDB operations are necessary for their flexibility and capability. Mongoose models offer direct access to their underlying collections, allowing you to harness the full power of MongoDB without leaving the comfort of Mongoose's organization and connection management. Whether you're optimizing your queries or integrating with systems dependent on raw commands, understanding these operations is an essential part of any Node.js and MongoDB developer's toolkit.


Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.