MongoDB Limit
Control query results and implement pagination with limit and skip
🎯 What is MongoDB Limit?
The limit() method in MongoDB restricts the number of documents returned by a query. Combined with skip(), it enables efficient pagination and result control. This is essential for performance optimization, especially when dealing with large datasets, as it prevents loading unnecessary data.
// Basic limit usage
db.users.find().limit(5) // Return only first 5 documents
// Limit with skip for pagination
db.products.find()
.skip(10) // Skip first 10 documents
.limit(5) // Return next 5 documents
// Limit with sorting
db.posts.find().sort({ date: -1 }).limit(3) // Latest 3 posts
Limit and Skip Methods
limit()
Restrict number of results
db.users.find().limit(10)
skip()
Skip specified number of documents
db.users.find().skip(20)
Pagination
Combine skip and limit
db.users.find()
.skip(20).limit(10)
With Sorting
Order results before limiting
db.posts.find()
.sort({ date: -1 })
.limit(5)
Basic Limit Operations
Learn how to control the number of documents returned by queries
// Sample data
db.products.insertMany([
{ _id: 1, name: "Laptop", price: 999, category: "electronics" },
{ _id: 2, name: "Phone", price: 599, category: "electronics" },
{ _id: 3, name: "Tablet", price: 399, category: "electronics" },
{ _id: 4, name: "Book", price: 19, category: "books" },
{ _id: 5, name: "Pen", price: 2, category: "stationery" },
{ _id: 6, name: "Notebook", price: 5, category: "stationery" },
{ _id: 7, name: "Mouse", price: 25, category: "electronics" },
{ _id: 8, name: "Keyboard", price: 75, category: "electronics" }
])
// Basic limit - get only first 3 documents
print("First 3 products:")
db.products.find().limit(3).forEach(printjson)
// Limit with filter - get first 2 electronics
print("\nFirst 2 electronics:")
db.products.find({ category: "electronics" }).limit(2).forEach(printjson)
// Limit with projection - get only names of first 4 products
print("\nFirst 4 product names:")
db.products.find({}, { name: 1, _id: 0 }).limit(4).forEach(printjson)
Skip and Pagination
Use skip() to implement pagination and navigate through large datasets
🔹 Basic Skip Operation
// Skip first 3 documents
print("Skip first 3 products:")
db.products.find().skip(3).forEach(printjson)
// Skip and limit together
print("\nSkip 2, limit 3 (products 3-5):")
db.products.find().skip(2).limit(3).forEach(printjson)
// Skip with filter
print("\nSkip first electronics item, get next 2:")
db.products.find({ category: "electronics" }).skip(1).limit(2).forEach(printjson)
🔹 Pagination Implementation
// Pagination function
function getPage(collection, pageNumber, pageSize, filter = {}) {
var skip = (pageNumber - 1) * pageSize
print(`Page ${pageNumber} (${pageSize} items per page):`)
var results = db[collection].find(filter)
.skip(skip)
.limit(pageSize)
.toArray()
results.forEach(printjson)
// Get total count for pagination info
var totalCount = db[collection].countDocuments(filter)
var totalPages = Math.ceil(totalCount / pageSize)
print(`\nShowing page ${pageNumber} of ${totalPages} (${results.length} items)`)
print(`Total items: ${totalCount}`)
return {
data: results,
currentPage: pageNumber,
totalPages: totalPages,
totalItems: totalCount,
hasNextPage: pageNumber < totalPages,
hasPrevPage: pageNumber > 1
}
}
// Usage examples
getPage("products", 1, 3) // First page, 3 items
print("\n" + "=".repeat(50) + "\n")
getPage("products", 2, 3) // Second page, 3 items
print("\n" + "=".repeat(50) + "\n")
getPage("products", 1, 2, { category: "electronics" }) // Electronics only
Limit with Sorting
Combine limit with sort to get top/bottom results
🔹 Top N Results
// Most expensive products (top 3)
print("Top 3 most expensive products:")
db.products.find().sort({ price: -1 }).limit(3).forEach(printjson)
// Cheapest products (bottom 3)
print("\nTop 3 cheapest products:")
db.products.find().sort({ price: 1 }).limit(3).forEach(printjson)
// Alphabetically first products
print("\nFirst 3 products alphabetically:")
db.products.find().sort({ name: 1 }).limit(3).forEach(printjson)
🔹 Category-wise Top Results
// Get top 2 products from each category
var categories = db.products.distinct("category")
categories.forEach(function(category) {
print(`\nTop 2 products in ${category}:`)
db.products.find({ category: category })
.sort({ price: -1 })
.limit(2)
.forEach(printjson)
})
Advanced Limit Techniques
Advanced patterns and optimizations for limit operations
🔹 Random Sampling
// Get random documents using aggregation
print("3 random products:")
db.products.aggregate([
{ $sample: { size: 3 } }
]).forEach(printjson)
// Alternative: Skip random amount (less efficient for large collections)
function getRandomDocuments(collection, count) {
var totalDocs = db[collection].countDocuments()
var randomSkip = Math.floor(Math.random() * (totalDocs - count))
return db[collection].find()
.skip(randomSkip)
.limit(count)
.toArray()
}
print("\nRandom products using skip:")
getRandomDocuments("products", 2).forEach(printjson)
🔹 Cursor-based Pagination (More Efficient)
// More efficient pagination for large datasets
function getCursorPage(collection, lastId = null, pageSize = 5, sortField = "_id") {
var query = {}
// If we have a lastId, start from there
if (lastId) {
query[sortField] = { $gt: lastId }
}
var results = db[collection].find(query)
.sort({ [sortField]: 1 })
.limit(pageSize + 1) // Get one extra to check if there's a next page
.toArray()
var hasNextPage = results.length > pageSize
if (hasNextPage) {
results.pop() // Remove the extra document
}
var nextCursor = results.length > 0 ? results[results.length - 1][sortField] : null
return {
data: results,
nextCursor: nextCursor,
hasNextPage: hasNextPage
}
}
// Usage
print("First page:")
var page1 = getCursorPage("products")
page1.data.forEach(printjson)
print("\nSecond page:")
var page2 = getCursorPage("products", page1.nextCursor)
page2.data.forEach(printjson)
print(`\nHas next page: ${page2.hasNextPage}`)
Performance Considerations
Best practices for efficient limit and skip operations
⚡ Performance Tips:
- Index your sort fields: Always create indexes on fields used in sort()
- Avoid large skip values: skip(10000) is slow - use cursor-based pagination
- Combine with filters: Filter first, then limit for better performance
- Use projection: Only return fields you need
🚫 Avoid These Patterns:
- Large skip values without indexes
- Sorting without indexes on sort fields
- Using limit() without understanding your data size
// Good: Create index for sorted queries
db.products.createIndex({ price: -1 })
db.products.createIndex({ category: 1, price: -1 })
// Good: Efficient query with index
db.products.find({ category: "electronics" })
.sort({ price: -1 })
.limit(10)
// Bad: Large skip without index (slow for large collections)
// db.products.find().skip(10000).limit(10) // Avoid this!
// Good: Use cursor-based pagination instead
function efficientPagination(minPrice = 0, limit = 10) {
return db.products.find({
category: "electronics",
price: { $gt: minPrice }
})
.sort({ price: 1 })
.limit(limit)
}
// Performance comparison function
function comparePerformance() {
print("Testing performance...")
// Method 1: Large skip (inefficient)
var start = new Date()
db.products.find().skip(1000).limit(10).toArray()
var skipTime = new Date() - start
// Method 2: Cursor-based (efficient)
start = new Date()
db.products.find({ _id: { $gt: ObjectId("507f1f77bcf86cd799439011") } })
.limit(10).toArray()
var cursorTime = new Date() - start
print(`Skip method: ${skipTime}ms`)
print(`Cursor method: ${cursorTime}ms`)
}
Practical Examples
Real-world applications of limit and skip
// Example 1: Blog post pagination
function getBlogPosts(page = 1, postsPerPage = 5) {
var skip = (page - 1) * postsPerPage
var posts = db.posts.find({ published: true })
.sort({ publishDate: -1 })
.skip(skip)
.limit(postsPerPage)
.toArray()
var totalPosts = db.posts.countDocuments({ published: true })
var totalPages = Math.ceil(totalPosts / postsPerPage)
return {
posts: posts,
pagination: {
currentPage: page,
totalPages: totalPages,
totalPosts: totalPosts,
hasNext: page < totalPages,
hasPrev: page > 1
}
}
}
// Example 2: Product search with pagination
function searchProducts(searchTerm, category = null, page = 1, limit = 10) {
var query = {
name: { $regex: searchTerm, $options: "i" }
}
if (category) {
query.category = category
}
var skip = (page - 1) * limit
var results = db.products.find(query)
.sort({ price: 1 })
.skip(skip)
.limit(limit)
.toArray()
var totalResults = db.products.countDocuments(query)
return {
results: results,
totalResults: totalResults,
page: page,
totalPages: Math.ceil(totalResults / limit)
}
}
// Example 3: Leaderboard (top scores)
function getLeaderboard(gameId, topN = 10) {
return db.scores.find({ gameId: gameId })
.sort({ score: -1, timestamp: 1 }) // Highest score first, earliest time for ties
.limit(topN)
.toArray()
}
// Example 4: Recent activity feed
function getRecentActivity(userId, limit = 20) {
return db.activities.find({
$or: [
{ userId: userId },
{ followers: userId }
]
})
.sort({ timestamp: -1 })
.limit(limit)
.toArray()
}
// Usage examples
print("Blog posts page 1:")
var blogPage = getBlogPosts(1, 3)
blogPage.posts.forEach(post => print(`- ${post.title}`))
print("\nSearch results for 'phone':")
var searchResults = searchProducts("phone", null, 1, 5)
searchResults.results.forEach(product => print(`- ${product.name}: $${product.price}`))
print("\nTop 5 leaderboard:")
var leaderboard = getLeaderboard("game123", 5)
leaderboard.forEach((entry, index) =>
print(`${index + 1}. ${entry.playerName}: ${entry.score}`)
)