Skip to main content

MongoDB Sort

Introduction

Sorting is a fundamental operation when working with databases. In MongoDB, the sort() method allows us to control the order in which query results are returned. Whether you need to display products from highest to lowest price, list users alphabetically, or arrange posts by date, sorting is essential for creating readable and useful outputs in your applications.

In this tutorial, we'll explore how to use MongoDB's sort functionality to organize our query results in meaningful ways.

Understanding MongoDB's Sort Method

The sort() method in MongoDB takes a document specifying the field(s) to sort by and the order of the sort. It can be applied to the results of a find() operation before the final results are returned.

Basic Syntax

javascript
db.collection.find().sort({ <field>: <sort order> })
  • <field>: The field name you want to sort by
  • <sort order>: Use 1 for ascending order or -1 for descending order

Basic Sorting Examples

Sort in Ascending Order

Let's start with a simple example. Suppose we have a products collection. To retrieve all products sorted by price in ascending order (lowest to highest):

javascript
db.products.find().sort({ price: 1 })

Output:

[
{ "_id": "1", "name": "Basic Pen", "price": 1.99, "category": "stationery" },
{ "_id": "2", "name": "Notebook", "price": 4.99, "category": "stationery" },
{ "_id": "3", "name": "Coffee Mug", "price": 8.99, "category": "kitchenware" },
{ "_id": "4", "name": "Desk Lamp", "price": 19.99, "category": "home" }
]

Sort in Descending Order

If you want to display the most expensive products first (highest to lowest price):

javascript
db.products.find().sort({ price: -1 })

Output:

[
{ "_id": "4", "name": "Desk Lamp", "price": 19.99, "category": "home" },
{ "_id": "3", "name": "Coffee Mug", "price": 8.99, "category": "kitchenware" },
{ "_id": "2", "name": "Notebook", "price": 4.99, "category": "stationery" },
{ "_id": "1", "name": "Basic Pen", "price": 1.99, "category": "stationery" }
]

Sorting on Multiple Fields

You can sort by multiple fields by including additional field:value pairs in the sort document. MongoDB will sort first by the first field specified, then by the second field, and so on.

Example: Sort by Category and Price

To sort products first by category (alphabetically) and then by price (lowest to highest):

javascript
db.products.find().sort({ category: 1, price: 1 })

Output:

[
{ "_id": "4", "name": "Desk Lamp", "price": 19.99, "category": "home" },
{ "_id": "3", "name": "Coffee Mug", "price": 8.99, "category": "kitchenware" },
{ "_id": "1", "name": "Basic Pen", "price": 1.99, "category": "stationery" },
{ "_id": "2", "name": "Notebook", "price": 4.99, "category": "stationery" }
]

Mixed Order Sorting

You can combine ascending and descending sorts in the same query. For example, to sort alphabetically by category but show the highest-priced items first within each category:

javascript
db.products.find().sort({ category: 1, price: -1 })

Output:

[
{ "_id": "4", "name": "Desk Lamp", "price": 19.99, "category": "home" },
{ "_id": "3", "name": "Coffee Mug", "price": 8.99, "category": "kitchenware" },
{ "_id": "2", "name": "Notebook", "price": 4.99, "category": "stationery" },
{ "_id": "1", "name": "Basic Pen", "price": 1.99, "category": "stationery" }
]

Sorting with Filtering

The sort method can be combined with query filters to first select specific documents and then sort them.

Example: Finding and Sorting Stationery Products

javascript
db.products.find({ category: "stationery" }).sort({ price: -1 })

Output:

[
{ "_id": "2", "name": "Notebook", "price": 4.99, "category": "stationery" },
{ "_id": "1", "name": "Basic Pen", "price": 1.99, "category": "stationery" }
]

Sorting on Nested Fields

If your documents contain nested objects, you can sort on fields within those objects using dot notation.

Example: Sorting on Nested Fields

Consider a collection of user profiles with nested address information:

javascript
db.users.find().sort({ "address.city": 1 })

Output:

[
{
"_id": "101",
"name": "Alice",
"address": { "city": "Boston", "state": "MA", "zip": "02115" }
},
{
"_id": "103",
"name": "Charlie",
"address": { "city": "Chicago", "state": "IL", "zip": "60601" }
},
{
"_id": "102",
"name": "Bob",
"address": { "city": "Seattle", "state": "WA", "zip": "98101" }
}
]

Sorting on Array Fields

When sorting on array fields, MongoDB uses the lowest value in the array for ascending sorts or the highest value for descending sorts.

Example: Sorting by Tags

javascript
// Sample blog posts with tags
db.posts.find().sort({ tags: 1 })

Output:

[
{ "_id": "p2", "title": "JavaScript Basics", "tags": ["beginner", "javascript", "tutorial"] },
{ "_id": "p1", "title": "Advanced MongoDB Tips", "tags": ["database", "mongodb", "tips"] },
{ "_id": "p3", "title": "Web Development Tools", "tags": ["tools", "web", "development"] }
]

In this case, the post "JavaScript Basics" appears first because "beginner" is alphabetically first among all tags.

Sorting on Dates

MongoDB stores dates as ISODate objects, which can be sorted chronologically.

Example: Sorting Posts by Creation Date

javascript
db.posts.find().sort({ createdAt: -1 })

Output:

[
{
"_id": "p3",
"title": "Web Development Tools",
"createdAt": ISODate("2023-11-15T10:30:00Z")
},
{
"_id": "p2",
"title": "JavaScript Basics",
"createdAt": ISODate("2023-10-20T14:15:00Z")
},
{
"_id": "p1",
"title": "Advanced MongoDB Tips",
"createdAt": ISODate("2023-09-05T08:45:00Z")
}
]

Combining Sort with Other Cursor Methods

MongoDB's sort can be combined with other cursor methods like limit(), skip(), and project() to create more complex queries.

Example: Pagination with Sort, Skip, and Limit

To implement simple pagination where you display 2 products per page, sorted by price:

javascript
// Page 1
db.products.find().sort({ price: 1 }).limit(2)

// Page 2
db.products.find().sort({ price: 1 }).skip(2).limit(2)

Output for Page 1:

[
{ "_id": "1", "name": "Basic Pen", "price": 1.99, "category": "stationery" },
{ "_id": "2", "name": "Notebook", "price": 4.99, "category": "stationery" }
]

Output for Page 2:

[
{ "_id": "3", "name": "Coffee Mug", "price": 8.99, "category": "kitchenware" },
{ "_id": "4", "name": "Desk Lamp", "price": 19.99, "category": "home" }
]
Important

The order of the methods matters. In MongoDB, you should typically use sort() before skip() and limit() for consistent results.

Performance Considerations

Using Indexes for Efficient Sorting

Sorting large collections without an appropriate index can be slow and memory-intensive. MongoDB will use an index for sorting if one exists on the sorted fields, significantly improving performance.

javascript
// Create an index on the price field
db.products.createIndex({ price: 1 })

// Now this sort will use the index
db.products.find().sort({ price: 1 })

Memory Limits for Sorting

MongoDB has a limit on how much memory it can use for sorting operations that cannot use an index. By default, this is 32MB. If a sort operation exceeds this limit, you'll receive an error.

To handle large sorts:

  1. Create an appropriate index
  2. Use the allowDiskUse option for aggregate operations (Note: this isn't available for the find() method's sort)
javascript
// For large sorts in aggregation pipeline
db.products.aggregate([
{ $sort: { price: 1 } }
], { allowDiskUse: true })

Real-World Applications

E-commerce Product Listing

In an e-commerce application, you might need to implement various sorting options for product listings:

javascript
// Sort by price: low to high
db.products.find({ category: "electronics" }).sort({ price: 1 })

// Sort by price: high to low
db.products.find({ category: "electronics" }).sort({ price: -1 })

// Sort by popularity and then by price
db.products.find({ category: "electronics" }).sort({ popularity: -1, price: 1 })

// Sort by newest first (assuming products have a createdAt field)
db.products.find({ category: "electronics" }).sort({ createdAt: -1 })

Social Media Feed

For a social media application, you might want to show posts in different orders:

javascript
// Show newest posts first
db.posts.find().sort({ postedAt: -1 })

// Show most liked posts first
db.posts.find().sort({ likes: -1 })

// Show posts from friends, newest first
db.posts.find({ userId: { $in: friendIds } }).sort({ postedAt: -1 })

Data Analysis

For analytical queries, you might need complex sorting:

javascript
// Find top-performing products by revenue
db.sales.aggregate([
{ $group: { _id: "$productId", totalRevenue: { $sum: "$price" } } },
{ $sort: { totalRevenue: -1 } },
{ $limit: 10 }
])

Summary

Sorting is an essential operation in MongoDB that allows you to control the order of query results. Key points to remember:

  • Use sort({ field: 1 }) for ascending order and sort({ field: -1 }) for descending order
  • You can sort on multiple fields for more complex ordering
  • Sorting works with nested fields using dot notation
  • Create indexes on commonly sorted fields for better performance
  • Combine sort with other cursor methods like limit() and skip() for pagination
  • The order of chained methods matters—typically use sort before skip and limit

By mastering MongoDB's sorting capabilities, you'll be able to present data in the most meaningful way for your application's users, whether you're building an e-commerce platform, a content management system, or a data analytics tool.

Exercises

  1. Create a collection of 10 books with fields for title, author, published date, and page count. Write a query to sort them by publication date (newest first).

  2. Extend the books collection to include a "ratings" array field containing user ratings. Write a query to find books with an average rating above 4, sorted alphabetically by title.

  3. Implement a simple pagination system for a blog that shows 5 posts per page, sorted by creation date (newest first).

  4. Create a compound index on the books collection to optimize a sort on author (ascending) and publication date (descending).

  5. Write an aggregation pipeline that groups books by author and sorts authors by their total number of published pages (highest first).

Further Reading



If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)