Top 10 MongoDB Queries
Tags: javascript, mongoose, mongodb, node
Published: 2023-09-08 15:35:08

[Mongoose](https://mongoosejs.com/) is a popular JavaScript library used with MongoDB, a NoSQL database. It provides an elegant and user-friendly way to interact with MongoDB from Node.js applications. Mongoose offers several key benefits:

1. **Schema-Based Modeling**: Mongoose allows you to define data schemas for your MongoDB collections, enforcing data structure and validation. This ensures data consistency and integrity.

2. **Easy Data Manipulation**: It simplifies CRUD operations by providing intuitive methods to create, read, update, and delete documents in MongoDB.

3. **Validation**: Mongoose offers built-in validation capabilities, allowing you to define rules for data validation, ensuring that only valid data is stored in the database.

4. **Middleware**: You can define middleware functions to execute custom logic before or after specific operations, such as saving or querying data.

5. **Query Building**: Mongoose provides a powerful query builder with support for filtering, sorting, and pagination, making it easier to construct complex database queries.

6. **Population**: Mongoose simplifies data referencing and population, allowing you to retrieve related data from other collections in a single query.

7. **Middleware Support**: It supports middleware functions to perform custom logic during document validation, saving, and other operations.

8. **Plugins**: Mongoose offers a plugin system that allows you to extend its functionality easily and reuse code across projects.

Overall, Mongoose streamlines MongoDB interaction, making it a popular choice for Node.js developers. It enhances development efficiency and ensures data consistency and validation in MongoDB-based applications.

---

Here are some sample queries for simple CRUD operations:

**Insert a Document:** 
Create and insert a new document into a MongoDB collection.
   ```javascript
   const newBook = new Book({ title: 'Sample Book', author: 'John Doe' });
   newBook.save();
   ```
**Find All Documents:** 
Retrieve all documents from a collection.
   ```javascript
   const allBooks = await Book.find();
   ```
**Find Documents with a Condition:**
   Retrieve documents that match a specific condition.
   ```javascript
   const fantasyBooks = await Book.find({ genre: 'Fantasy' });
   ```
**Find One Document:**
   Retrieve a single document based on a condition.
   ```javascript
   const book = await Book.findOne({ title: 'Sample Book' });
   ```
**Update a Document:**
   Update a document's fields.

   ```javascript
   await Book.updateOne({ title: 'Sample Book' }, { $set: { genre: 'Science Fiction' } });
   ```
**Delete a Document:**
   Delete a document based on a condition.

   ```javascript
   await Book.deleteOne({ title: 'Sample Book' });
   ```
**Aggregate Data:**
   Perform data aggregation operations using the aggregation pipeline.

   ```javascript
   const result = await Book.aggregate([
     { $match: { genre: 'Science Fiction' } },
     { $group: { _id: '$author', totalBooks: { $sum: 1 } } }
   ]);
   ```
**Sorting Documents:**
   Sort documents based on a field.

   ```javascript
   const sortedBooks = await Book.find().sort({ title: 1 }); // Ascending order
   ```
**Limit and Skip Results:**
   Limit the number of documents returned and skip some results.
   ```javascript
   const page1 = await Book.find().skip(0).limit(10); // First 10 documents
   const page2 = await Book.find().skip(10).limit(10); // Next 10 documents
   ```
**Populate References:**
Populate documents with references from other collections.
```javascript
    const user = await User.findOne().populate('books'); // Assuming 'books' is a reference field
```

---

Sample Mongoose queries for building a search API:

**Basic Text Search:**
   Search for documents that contain a specific text in a field.

   ```javascript
   const searchQuery = 'apple';
   const results = await Product.find({ $text: { $search: searchQuery } });
   ```
**Case-Insensitive Search:**
   Perform a case-insensitive text search.

   ```javascript
   const searchQuery = 'apple';
   const results = await Product.find({
     productName: { $regex: new RegExp(searchQuery, 'i') }
   });
   ```
**Search by Multiple Conditions:**
   Combine multiple search conditions using the `$and` or `$or` operator.

   ```javascript
   const searchQuery1 = 'apple';
   const searchQuery2 = 'red';
   const results = await Product.find({
     $or: [
       { productName: { $regex: new RegExp(searchQuery1, 'i') } },
       { color: { $regex: new RegExp(searchQuery2, 'i') } }
     ]
   });
   ```
**Search by Date Range:**
   Search for documents within a specific date range.

   ```javascript
   const startDate = new Date('2023-01-01');
   const endDate = new Date('2023-12-31');
   const results = await Event.find({
     eventDate: { $gte: startDate, $lte: endDate }
   });
   ```
**Partial Match Search:**
   Search for documents where a field partially matches the search query.

   ```javascript
   const searchQuery = 'app';
   const results = await Product.find({
     productName: { $regex: new RegExp(searchQuery, 'i') }
   });
   ```
**Search with Pagination:**
   Implement pagination for search results.

   ```javascript
   const page = 1;
   const perPage = 10;
   const skip = (page - 1) * perPage;
   const results = await Product.find({}).skip(skip).limit(perPage);
   ```
**Sorting Search Results:**
   Sort search results based on a field.

   ```javascript
   const sortBy = 'price'; // Field to sort by
   const sortOrder = 'asc'; // 'asc' or 'desc'
   const results = await Product.find({}).sort({ [sortBy]: sortOrder });
   ```
**Search with Full-Text Index and Weighting:**
   Perform a full-text search with weighting for certain fields.

   ```javascript
   const searchQuery = 'apple';
   const results = await Product.find({
     $text: { $search: searchQuery },
     $meta: { $textScore: { $gte: 1 } }
   }).sort({ score: { $meta: 'textScore' } });
   ```
**Search by Array Elements:**
   Search for documents that contain specific elements in an array field.

   ```javascript
   const searchQuery = 'red';
   const results = await Product.find({ colors: searchQuery });
   ```
**Search with Regular Expression:**
Search for documents that match a field using a regular expression.
```javascript
    const searchQuery = '^abc';
    const results = await Product.find({ productName: { $regex: searchQuery } });
```

---

Sample Mongoose aggregation queries to perform complex data transformations and calculations:

**Group and Count Documents:**
   Group documents by a field and count the occurrences.

   ```javascript
   const result = await Order.aggregate([
     { $group: { _id: '$product', count: { $sum: 1 } } }
   ]);
   ```
**Calculate Average:**
   Calculate the average of a numeric field.

   ```javascript
   const result = await Product.aggregate([
     { $group: { _id: null, avgPrice: { $avg: '$price' } } }
   ]);
   ```

**Filter and Group:**
   Filter documents and then group them.

   ```javascript
   const result = await Transaction.aggregate([
     { $match: { status: 'completed' } },
     { $group: { _id: '$product', total: { $sum: '$amount' } } }
   ]);
   ```

**Sort and Limit:**
   Sort documents and limit the result set.

   ```javascript
   const result = await Product.aggregate([
     { $sort: { price: -1 } },
     { $limit: 5 }
   ]);
   ```
**Unwind Array:**
   Unwind an array field to create separate documents for each array element.

   ```javascript
   const result = await Order.aggregate([
     { $unwind: '$items' }
   ]);
   ```
**Project Specific Fields:**
   Project specific fields to include in the result.

   ```javascript
   const result = await User.aggregate([
     { $project: { name: 1, email: 1 } }
   ]);
   ```
**Lookup and Populate:**
   Perform a lookup operation to join data from another collection.
   ```javascript
   const result = await Order.aggregate([
     {
       $lookup: {
         from: 'products',
         localField: 'productId',
         foreignField: '_id',
         as: 'product'
       }
     }
   ]);
   ```
**Date Aggregation:**
   Extract and group data by date.

   ```javascript
   const result = await Log.aggregate([
     {
       $group: {
         _id: { $dateToString: { format: '%Y-%m-%d', date: '$timestamp' } },
         count: { $sum: 1 }
       }
     }
   ]);
   ```
**Conditional Aggregation:**
   Perform conditional aggregations based on field values.
   ```javascript
   const result = await Sales.aggregate([
     {
       $group: {
         _id: '$product',
         totalSales: {
           $sum: {
             $cond: [{ $eq: ['$status', 'sold'] }, '$quantity', 0]
           }
         }
       }
     }
   ]);
   ```

**Bucketing Data:**
Bucket data into predefined ranges.
```javascript
    const result = await Product.aggregate([
      {
        $bucket: {
          groupBy: '$price',
          boundaries: [0, 100, 200, 300],
          default: 'Other',
          output: {
            count: { $sum: 1 },
            avgPrice: { $avg: '$price' }
          }
        }
      }
    ]);
```