MongoDB: Sorting by a single field and multiple fields (with examples)

Updated: February 3, 2024 By: Guest Contributor Post a comment

Introduction

Sorting is a fundamental operation in database management which allows users to analyse and visualize data in an organized manner. MongoDB, being a leading NoSQL database, provides powerful sorting mechanisms to effectively order result sets either in ascending or descending order. In this tutorial, we will explore how to perform sorting in MongoDB by a single field as well as by multiple fields, accompanied by practical examples.

Understanding MongoDB Sort Method

In MongoDB, the sort() method is used to sort data in any given collection. To apply sorting, we include this method in our database query, providing a document specifying the field or fields to sort by, along with the direction of the sort. Ascending order is denoted by 1, while descending order is represented by -1.

Basic Sorting by a Single Field

db.collection.find().sort({ field: 1 }); // ascending order

db.collection.find().sort({ field: -1 }); // descending order

To illustrate, if we wanted to sort documents in a collection named ‘users’ by their ‘username’ field in ascending order, the query would be:

db.users.find().sort({ username: 1 });

Given a collection with the following documents:

{ _id: 1, username: 'jdoe', age: 30 }
{ _id: 2, username: 'asmith', age: 26 }
{ _id: 3, username: 'bjones', age: 28 }

The result of the above sort query would be:

{ _id: 2, username: 'asmith', age: 26 }
{ _id: 3, username: 'bjones', age: 28 }
{ _id: 1, username: 'jdoe', age: 30 }

Sorting by Multiple Fields

When sorting by multiple fields, you specify a priority order in which the sorting should occur. If two documents have the same value for the first field, MongoDB will sort them based on the second field, and so on.

db.collection.find().sort({ firstField: 1, secondField: -1 });

For example, to sort the ‘users’ collection first by ‘age’ in ascending order, then by ‘username’ in descending order, the query would be:

db.users.find().sort({ age: 1, username: -1 });

This will yield results where users are primarily sorted by age, and users with the same age are then sorted by username in reverse alphabetical order.

Assuming the same collection from earlier, plus an additional document, the sorted result set will look like this:

{ _id: 2, username: 'asmith', age: 26 }
{ _id: 4, username: 'mjane', age: 26 }
{ _id: 3, username: 'bjones', age: 28 }
{ _id: 1, username: 'jdoe', age: 30 }

In this set, ‘asmith’ and ‘mjane’ share the same age, so they are sorted by username with ‘mjane’ appearing before ‘asmith’ since we used descending order for the username field.

Advanced Sorting Techniques

Beyond basic sorting, MongoDB also allows for more complex sorting patterns such as sorting subdocuments, array fields, and aggregations.

Sorting Subdocuments: To sort based on fields within a subdocument, you use dot notation.

db.collection.find().sort({ 'address.city': 1 });

Sorting Array Fields: You can sort by the size of an array or the elements within it.

// Sorts the collection by the first element in the 'tags' array in ascending order.
db.collection.find().sort({ 'tags': 1 });

// To sort by the size of the 'tags' array in descending order:
db.collection.aggregate([
  {
    $project: {
      name: 1,
      numberOfTags: { $size: '$tags' }
    }
  },
  {
    $sort: { numberOfTags: -1 }
  }
]);

Utilizing Indexes for Sorting: If a query can use an index to fulfill the sort, it will often be much faster. Creating appropriate indexes can significantly improve sort performance.

Sorting with Aggregation

The aggregation framework provides greater flexibility with the $sort stage. It allows sorting not just by document fields, but also by computed values and expressions.

db.collection.aggregate([
  { $match: { status: 'A' } },
  { $group: { _id: '$cust_id', total: { $sum: '$amount' } } },
  { $sort: { total: -1 } }
]);

This aggregation pipeline would first filter documents by status, group them by customer ID to calculate the total amount spent, and finally sort the results in descending order of the total.

Handling Null Values and Missing Fields

It’s important to be mindful of how null values and missing fields are handled while sorting. In MongoDB, null values are considered to be less than all other values during sorting. Therefore, if you sort in ascending order, documents with null or missing fields will appear first.

Given the explanation of how MongoDB sorts documents with null values and missing fields in ascending order, here are some sample results for a hypothetical collection users sorted by a field named age in ascending order:

Before Sorting:

{ "_id": 1, "name": "John Doe", "age": 30 }
{ "_id": 2, "name": "Jane Smith" } // 'age' is missing
{ "_id": 3, "name": "Alice Johnson", "age": null }
{ "_id": 4, "name": "Bob Brown", "age": 25 }
{ "_id": 5, "name": "Charlie Black", "age": 35 }

Command:

db.users.find().sort({ age: 1 });

After Sorting (Ascending by age):

{ "_id": 2, "name": "Jane Smith" } // 'age' is missing, considered less than null
{ "_id": 3, "name": "Alice Johnson", "age": null } // null is less than any other value
{ "_id": 4, "name": "Bob Brown", "age": 25 } // Non-null values sorted in ascending order
{ "_id": 1, "name": "John Doe", "age": 30 }
{ "_id": 5, "name": "Charlie Black", "age": 35 }

In this example:

  • The document with the missing age field (_id: 2) and the document with age set to null (_id: 3) are sorted to appear first because null and missing values are considered to be less than all other values during sorting.
  • The remaining documents are then sorted in ascending order based on the age field.

Conclusion

Sorting in MongoDB is a versatile feature that can be applied to single or multiple fields, with additional refinement possible through indexes, aggregations, and handling of complex field types. By mastering sorting in MongoDB, you can retrieve data in a way that best fits your application’s needs.