MongoDB 3.6聚合函数报错求助:需指定cursor选项
Hey there! I’ve run into this exact issue when upgrading from MongoDB 3.4 to 3.6, so let’s break down what’s happening and how to fix it.
What’s the Root Cause?
MongoDB 3.6 introduced a breaking change for the aggregate() method: it now requires the cursor option by default. In 3.4, you could omit this option and get a direct array of results back, but 3.6 enforces using a cursor (unless you’re running an aggregate with the explain argument). This shift was made to better handle large result sets that can’t fit entirely in memory, as cursors fetch data in batches.
How to Fix It
Depending on where you’re running your aggregate queries (shell, Node.js, etc.), here’s what you need to adjust:
1. MongoDB Shell
Old 3.4-compatible code (no cursor):
db.yourCollection.aggregate([ { $match: { status: "active" } }, { $group: { _id: "$category", total: { $sum: 1 } } } ]);
Updated 3.6 code (add cursor option):
// Basic cursor (uses default batch size) db.yourCollection.aggregate([ { $match: { status: "active" } }, { $group: { _id: "$category", total: { $sum: 1 } } } ], { cursor: {} }); // Or specify a custom batch size if needed db.yourCollection.aggregate([/* your stages */], { cursor: { batchSize: 500 } });
2. Node.js Native Driver
If you’re using the official MongoDB Node.js driver, the old code might have expected a direct result array. Now you’ll get a Cursor object, so you need to use toArray() to convert it:
Old code:
collection.aggregate([/* stages */], (err, results) => { // results was an array in 3.4 });
Updated code:
// Callback style collection.aggregate([/* stages */], { cursor: {} }) .toArray((err, results) => { // results is now the array you expect }); // Async/await style (cleaner for modern code) const results = await collection.aggregate([/* stages */], { cursor: {} }).toArray();
3. Mongoose
Mongoose abstracts some of this, but if you still hit the error, explicitly add the cursor option:
// Promise style YourModel.aggregate([/* stages */], { cursor: {} }) .then(results => { // handle results }) .catch(err => { // handle error }); // Async/await const results = await YourModel.aggregate([/* stages */], { cursor: {} });
Quick Note
If you were relying on the immediate array return from 3.4, don’t forget that the cursor object won’t give you the data directly—you need to call toArray() (or iterate through the cursor with next() if dealing with very large datasets) to get the actual results.
内容的提问来源于stack exchange,提问作者Ankur

