diff --git a/lib/cursor/queryCursor.js b/lib/cursor/queryCursor.js index ff59f6aeba8..2c908de50d0 100644 --- a/lib/cursor/queryCursor.js +++ b/lib/cursor/queryCursor.js @@ -10,6 +10,7 @@ const eachAsync = require('../helpers/cursor/eachAsync'); const helpers = require('../queryHelpers'); const kareem = require('kareem'); const immediate = require('../helpers/immediate'); +const { once } = require('node:events'); const util = require('util'); /** @@ -135,6 +136,25 @@ QueryCursor.prototype._read = function() { }); }; +/** + * Returns the underlying cursor from the MongoDB Node driver that this cursor uses. + * + * @method getDriverCursor + * @memberOf QueryCursor + * @returns {Cursor} MongoDB Node driver cursor instance + * @instance + * @api public + */ + +QueryCursor.prototype.getDriverCursor = async function getDriverCursor() { + if (this.cursor) { + return this.cursor; + } + + await once(this, 'cursor'); + return this.cursor; +}; + /** * Registers a transform function which subsequently maps documents retrieved * via the streams interface or `.next()` diff --git a/test/query.cursor.test.js b/test/query.cursor.test.js index d835135a0b2..a5f7afc2027 100644 --- a/test/query.cursor.test.js +++ b/test/query.cursor.test.js @@ -900,6 +900,25 @@ describe('QueryCursor', function() { assert.ok(err); assert.ok(err.message.includes('skipMiddlewareFunction'), err.message); }); + + it('returns the underlying Node driver cursor with getDriverCursor()', async function() { + const schema = new mongoose.Schema({ name: String }); + + const Movie = db.model('Movie', schema); + + await Movie.deleteMany({}); + await Movie.create([ + { name: 'Kickboxer' }, + { name: 'Ip Man' }, + { name: 'Enter the Dragon' } + ]); + + const cursor = await Movie.find({}).cursor(); + assert.ok(!cursor.cursor); + const driverCursor = await cursor.getDriverCursor(); + assert.ok(cursor.cursor); + assert.equal(driverCursor, cursor.cursor); + }); }); async function delay(ms) {