'Mongoose populate virtual with sort and limit

I am trying to write a mongoose query that retrieves a group of assets along with the most recent transactions for those assets. The transactions are in a separate collection from the assets.

To accomplish this, first I created a virtual array in the asset model to link the assets to the transactions.

schema.virtual('transactions', {
    ref: 'transaction',
    localField: '_id',
    foreignField: '_asset',
    justOne: false
})

Then I query using .populate in an node.js express controller (note the hard-coded "limit: 1" will become N at some point):

exports.getList = function (req, res) {
    Model
        .find({}, { __v: 0 })
        .populate({
            path: 'transactions',
            options: { sort: { 'created_at': -1}, limit: 1},
        })
        .lean()
        .exec(function (err, model) {
            if (err)
                res.send(err);
            res.json(model);
        });
  }

With 3 assets in my test system and a bunch of transactions for each one, it is returning old transactions for the first two assets and nothing for the third one.

When I remove the "limit:1" and return all transactions, it sorts properly and returns transactions for all three assets.

I believe I am running into this bug:

https://github.com/Automattic/mongoose/issues/4321

Any ideas on an elegant workaround?
Returning all transactions will not be a viable long-term solution.



Solution 1:[1]

For those reading this in 2021, as of mongoose 5.12.3 following can be done in model:

schema.virtual('transactions', {
    ref: 'transaction',
    localField: '_id',
    foreignField: '_asset',
    justOne: false,
    options: { sort: { 'createdAt': -1}, limit: 1},
})

Then in controller:

exports.getList = function (req, res) {
    Model
        .find({})
        .populate({
            path: 'transactions',
        })
        .lean()
        .exec(function (err, model) {
            if (err)
                res.send(err);
            res.json(model);
        });
  }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1