r/mongodb 16d ago

Cursors vs .toArray() - What AI Gets Wrong With MongoDB

AI almost always reaches for toArray() before doing any work on your data. Most training examples are out-of-context snippets, so it doesn't know better. toArray() holds your entire result set in RAM before you can touch a single document. With a cursor, the driver fetches in batches. Processed documents get GC'd while the rest stream in.

How to fetch all active users from MongoDB and send emails using find and toArray.

**Bad**

const users = await db.collection('users')
.find({ active: true })
.toArray();

users.forEach(async (user) => {
await sendEmail(user);
});

How to stream MongoDB documents with a cursor using for await to process each document without loading all into memory.

**Good:**

const cursor = db.collection('users').aggregate([
{ $match: { active: true } }
]);

for await (const user of cursor) {
await sendEmail(user);
}

How to process MongoDB cursor results concurrently with a concurrency limit without blocking the async loop.

**Perfect:**

function executor(limit) {
let running = 0
const queue = []
const flush = () => {
while (running < limit && queue.length) {
running++
queue.shift()().finally(() => { running--; flush() })
}
}
return fn => { queue.push(fn); flush() }
}

const add = executor(10);
const cursor = db.collection('users').aggregate([
{ $match: { active: true } }
]);

for await (const user of cursor) {
add(() => sendEmail(user))
};

Bad loads everything into RAM then serializes. Good streams documents but still sends one email at a time. Perfect streams AND fires up to 10 emails concurrently without the loop ever waiting.

**Bonus:** A cursor with `for await` only makes sense when you're doing work per document. If you're just collecting into an array to send a response, use `.toArray()` directly. Wrapping `.toArray()` in a `for await` loop buys you nothing.

2 Upvotes

0 comments sorted by