W3docs

MongoDB Sort

Learn how to sort MongoDB query results in Python using PyMongo's sort() method — ascending, descending, multi-key, combined with limit and filter.

This chapter explains how to sort MongoDB query results in Python using the pymongo driver. You will learn to sort on a single field in ascending or descending order, sort on multiple fields at once, combine sorting with filtering and limiting, and understand when an index makes sorting fast.

Prerequisites

You should be familiar with connecting to MongoDB and querying documents. If you have not done that yet, read MongoDB Find and MongoDB Query first.

The examples below assume a collection called products in a database called store. You can insert the sample documents used throughout this page with:

import pymongo

client = pymongo.MongoClient("mongodb://localhost:27017/")
db = client["store"]
col = db["products"]

# Insert sample data (skip if already inserted)
col.drop()
col.insert_many([
    {"name": "Keyboard", "category": "Electronics", "price": 49.99, "stock": 120},
    {"name": "Mouse",    "category": "Electronics", "price": 29.99, "stock": 85},
    {"name": "Desk",     "category": "Furniture",   "price": 249.99, "stock": 30},
    {"name": "Chair",    "category": "Furniture",   "price": 189.99, "stock": 45},
    {"name": "Monitor",  "category": "Electronics", "price": 319.99, "stock": 60},
    {"name": "Lamp",     "category": "Furniture",   "price": 39.99,  "stock": 200},
])
print("Sample data inserted.")

The sort() Method

The sort() method is called on a cursor (the object returned by find()) and tells MongoDB in what order to return documents. Its signature is:

cursor.sort(key_or_list, direction=None)
  • key_or_list — a field name (string) when sorting on a single field, or a list of (field, direction) tuples when sorting on multiple fields.
  • directionpymongo.ASCENDING (value 1) or pymongo.DESCENDING (value -1). Required when key_or_list is a plain string; omit it when using the list form.

Using the named constants (pymongo.ASCENDING / pymongo.DESCENDING) instead of raw integers makes code easier to read and avoids off-by-one mistakes.

Sorting in Ascending Order

Pass pymongo.ASCENDING as the second argument to sort from lowest to highest value:

import pymongo

client = pymongo.MongoClient("mongodb://localhost:27017/")
db = client["store"]
col = db["products"]

results = col.find({}, {"_id": 0, "name": 1, "price": 1}).sort("price", pymongo.ASCENDING)

for doc in results:
    print(doc)

Expected output (cheapest first):

{'name': 'Mouse', 'price': 29.99}
{'name': 'Lamp', 'price': 39.99}
{'name': 'Keyboard', 'price': 49.99}
{'name': 'Chair', 'price': 189.99}
{'name': 'Desk', 'price': 249.99}
{'name': 'Monitor', 'price': 319.99}

The projection {"_id": 0, "name": 1, "price": 1} limits the returned fields to name and price, which keeps output concise. Projections are covered in MongoDB Find.

Sorting in Descending Order

Pass pymongo.DESCENDING to reverse the order (highest to lowest):

import pymongo

client = pymongo.MongoClient("mongodb://localhost:27017/")
db = client["store"]
col = db["products"]

results = col.find({}, {"_id": 0, "name": 1, "price": 1}).sort("price", pymongo.DESCENDING)

for doc in results:
    print(doc)

Expected output (most expensive first):

{'name': 'Monitor', 'price': 319.99}
{'name': 'Desk', 'price': 249.99}
{'name': 'Chair', 'price': 189.99}
{'name': 'Keyboard', 'price': 49.99}
{'name': 'Lamp', 'price': 39.99}
{'name': 'Mouse', 'price': 29.99}

Sorting on Multiple Fields

When you want to sort by more than one field — for example, by category first and then by price within each category — pass a list of (field, direction) tuples:

import pymongo

client = pymongo.MongoClient("mongodb://localhost:27017/")
db = client["store"]
col = db["products"]

results = col.find({}, {"_id": 0, "name": 1, "category": 1, "price": 1}).sort([
    ("category", pymongo.ASCENDING),
    ("price",    pymongo.ASCENDING),
])

for doc in results:
    print(doc)

Expected output (categories A-Z, cheapest first within each category):

{'name': 'Mouse', 'category': 'Electronics', 'price': 29.99}
{'name': 'Keyboard', 'category': 'Electronics', 'price': 49.99}
{'name': 'Monitor', 'category': 'Electronics', 'price': 319.99}
{'name': 'Lamp', 'category': 'Furniture', 'price': 39.99}
{'name': 'Chair', 'category': 'Furniture', 'price': 189.99}
{'name': 'Desk', 'category': 'Furniture', 'price': 249.99}

The sort fields are applied left to right: MongoDB first sorts all documents by category, then breaks ties within the same category value by price.

Combining sort() with Filtering

sort() works with any query filter. The filter selects which documents match; sort() then orders only those matched documents:

import pymongo

client = pymongo.MongoClient("mongodb://localhost:27017/")
db = client["store"]
col = db["products"]

# Find Electronics only, sorted cheapest first
query  = {"category": "Electronics"}
fields = {"_id": 0, "name": 1, "price": 1}

results = col.find(query, fields).sort("price", pymongo.ASCENDING)

for doc in results:
    print(doc)

Expected output:

{'name': 'Mouse', 'price': 29.99}
{'name': 'Keyboard', 'price': 49.99}
{'name': 'Monitor', 'price': 319.99}

See MongoDB Query for more filtering options such as range queries ($gt, $lt) and pattern matching.

Combining sort() with limit()

Chain limit() after sort() to get the top (or bottom) N documents. The order of chaining does not matter — MongoDB always applies the sort before the limit:

import pymongo

client = pymongo.MongoClient("mongodb://localhost:27017/")
db = client["store"]
col = db["products"]

# Top 3 most expensive products
results = col.find({}, {"_id": 0, "name": 1, "price": 1}) \
             .sort("price", pymongo.DESCENDING) \
             .limit(3)

for doc in results:
    print(doc)

Expected output:

{'name': 'Monitor', 'price': 319.99}
{'name': 'Desk', 'price': 249.99}
{'name': 'Chair', 'price': 189.99}

Read MongoDB Limit for more on controlling the number of returned documents.

Performance: Use an Index for Large Collections

For small collections, MongoDB sorts results in memory. On a large collection, an in-memory sort can be slow and — if it exceeds 100 MB — MongoDB will return an error. Creating an index on the sort field lets MongoDB return pre-ordered data without scanning the whole collection:

import pymongo

client = pymongo.MongoClient("mongodb://localhost:27017/")
db = client["store"]
col = db["products"]

# Create a single-field index on price (ascending)
col.create_index([("price", pymongo.ASCENDING)])

# Queries that sort by price now use the index automatically
results = col.find({}, {"_id": 0, "name": 1, "price": 1}).sort("price", pymongo.ASCENDING)

for doc in results:
    print(doc)

For multi-field sorts, create a compound index whose fields and directions match your sort:

col.create_index([
    ("category", pymongo.ASCENDING),
    ("price",    pymongo.ASCENDING),
])

You only need to create each index once. Repeated calls to create_index() with the same key are safe — PyMongo checks whether the index already exists.

Storing the Connection String Safely

The examples above hardcode the connection string for simplicity. In a real application, store it in an environment variable:

import os
import pymongo

client = pymongo.MongoClient(os.environ["MONGODB_URI"])

Set the variable in your shell (export MONGODB_URI="mongodb://localhost:27017/") or use a .env file with a library such as python-dotenv.

Summary

GoalCode pattern
Sort ascending.sort("field", pymongo.ASCENDING)
Sort descending.sort("field", pymongo.DESCENDING)
Sort on multiple fields.sort([("f1", pymongo.ASCENDING), ("f2", pymongo.DESCENDING)])
Top N results.sort(...).limit(N)
Fast sort on large dataCreate an index on the sort field

Related chapters in this series:

Was this page helpful?