Am 10.03.2018 um 16:26 schrieb Carl Sturtivant:

On Sat, 10 Mar 2018 09:41:11 GMT, Sönke Ludwig wrote:

To work around the issue, the aggregate expression can be embedded into an array literal:

db[collection].aggregate(
     [["$group":["_id":"$"~variable]]]
)

The documentation
https://vibed.org/api/vibe.db.mongo.collection/MongoCollection.aggregate
presents two templates.

Bson aggregate(ARGS...) (
   ARGS pipeline
);

MongoCursor!R aggregate(R, S) (
   S[] pipeline,
   AggregateOptions options
);

and yet says further down the page it says,

Returns

An array of documents returned by the pipeline

This seems to contradict the second template.

This was an oversight during the aggregate overhaul that happened for
this release, I'll rephrase that appropriately.

Presumably the original code that wouldn't compile used the first template, and this fix that does compile would seem to use the second which returns a cursor, not a Bson list of documents, correct?

With the workaround, it will still match the first overload, but it hits
a different path inside, which doesn't invoke the serialization code
that failed to compile. The failing code path was also added/modified
during the aggregate overhaul.

More generally than my example and its workaround fix, is it true that use of the first template is limited by the 16MB hard limit on query result size in mongodb, so the returned Bson list must be inside this limit?

Whereas presumably use of the second template may produce (via the returned cursor) a sequence of documents whose summed size is not limited to 16MB, as long as each individual document is inside that limit, correct?

The first overload is based on the second MongoCursor based one, so,
despite the return value being a single Bson, the limit in both cases
only applies to each individual document returned, not to the whole
aggregate result.

However, because assembling this single Bson value is usually
unnecessarily memory intensive, it still makes sense to use the second
overload instead (by passing AggregateOptions.init as a second argument).