Reputation: 3388
Long time listener, first time caller here.
I'm using node drivers to execute an aggregate command on mongo and the $out
stage seems to only take effect if certain methods are chained.
I want to call aggregate()
with $out as the last stage of the pipeline and then callback. Currently, it only works if I chain next()
or toArray()
which is irksome since the method signature is aggregate(pipeline, options, callback).
Examples below simplified for clarity.
Here, I use the callback and $out does NOT take effect (i.e. newNames isn't created but the callback is executed). I'm refactoring stuff from a few months back and this was working previously (version 2.2.33 of the node driver):
db.collection('names')
.aggregate([
{ $match: {} },
{ $limit: 1 },
{ $out: 'newNames' }
], (err, result) => {
// result is an AggregationCursor
callback();
});
If I don't add a callback but chain next() instead, the $out stage DOES take effect
db.collection('names')
.aggregate([
{ $match: {} },
{ $limit: 1 },
{ $out: 'newNames' }
])
.next((err, result) => {
// result is null, why?
callback();
});
It also DOES work if you chain toArray:
db.collection('names')
.aggregate([
{ $match: {} },
{ $limit: 1 },
{ $out: 'newNames' }
])
.toArray((err, result) => {
// result is an empty array (i.e. the resulting docs), OK, makes sense
callback();
});
So I thought I must be misunderstanding Promises vs callbacks, but it does NOT take effect if I use close() either which is chained and the result is back to being an AggregationCursor:
db.collection('names')
.aggregate([
{ $match: {} },
{ $limit: 1 },
{ $out: 'newNames' }
])
.close((err, result) => {
// result is an AggregationCursor
callback();
});
Reading through some of the responses to issues, it seems the AggregationCursor vs Resulting Documents is expected. But I don't get why $out isn't taking effect when I go to the callback or chain close().
Upvotes: 3
Views: 1792
Reputation: 71
I just ran into this myself too. I called cursor.next() until a null was received and the $out aggregation worked. Using async / await makes this easy. Without these this could get pretty messy looking.
var cursor = await db.collection('names')
.aggregate([
{ $match: {} },
{ $limit: 1 },
{ $out: 'newNames' }
]);
var next = null;
do {
next = await cursor.next();
} while (next != null);
Upvotes: 7