diff --git a/src/extend-aggregate.js b/src/extend-aggregate.js index b7d4f12..b5b66d7 100644 --- a/src/extend-aggregate.js +++ b/src/extend-aggregate.js @@ -1,6 +1,7 @@ 'use strict'; const generateKey = require('./generate-key'); +const recoverObjectId = require('./recover-objectid'); let hasBeenExtended = false; module.exports = function(mongoose, cache) { @@ -28,7 +29,9 @@ module.exports = function(mongoose, cache) { return new Promise((resolve, reject) => { cache.get(key, (err, cachedResults) => { //eslint-disable-line handle-callback-err - if (cachedResults) { + if (cachedResults != null) { + cachedResults = recoverObjectId(mongoose, cachedResults); + callback(null, cachedResults); return resolve(cachedResults); } diff --git a/src/extend-query.js b/src/extend-query.js index 8089ffb..118bbb9 100644 --- a/src/extend-query.js +++ b/src/extend-query.js @@ -1,6 +1,7 @@ 'use strict'; const generateKey = require('./generate-key'); +const recoverObjectId = require('./recover-objectid'); module.exports = function(mongoose, cache) { const exec = mongoose.Query.prototype.exec; @@ -34,6 +35,8 @@ module.exports = function(mongoose, cache) { cachedResults = Array.isArray(cachedResults) ? cachedResults.map(hydrateModel(constructor)) : hydrateModel(constructor)(cachedResults); + } else { + cachedResults = recoverObjectId(mongoose, cachedResults); } callback(null, cachedResults); diff --git a/src/recover-objectid.js b/src/recover-objectid.js new file mode 100644 index 0000000..6010f77 --- /dev/null +++ b/src/recover-objectid.js @@ -0,0 +1,25 @@ +'use strict'; + +module.exports = function(mongoose, cachedResults) { + if (!Array.isArray(cachedResults)) { + return recoverObjectId(mongoose, cachedResults); + } + + const recoveredResult = []; + + for (const doc of cachedResults) { + recoveredResult.push(recoverObjectId(mongoose, doc)); + } + + return recoveredResult; +}; + +function recoverObjectId(mongoose, doc) { + if (!doc._id) { + return doc; + } + + // eslint-disable-next-line new-cap + doc._id = mongoose.Types.ObjectId(doc._id); + return doc; +} diff --git a/test/index.js b/test/index.js index 215d822..9199e3d 100644 --- a/test/index.js +++ b/test/index.js @@ -351,6 +351,30 @@ describe('cachegoose', () => { const diffSort = await getAllSorted({ num: -1 }); diffSort.length.should.equal(20); }); + + it('should return similar _id in cached array result for lean', async () => { + const originalRes = await getAllLean(60); + const cachedRes = await getAllLean(60); + const originalConstructor = originalRes[0]._id.constructor.name.should; + const cachedConstructor = cachedRes[0]._id.constructor.name.should; + originalConstructor.should.deepEqual(cachedConstructor); + }); + + it('should return similar _id in one cached result for lean', async () => { + const originalRes = await getOneLean(60); + const cachedRes = await getOneLean(60); + const originalConstructor = originalRes._id.constructor.name.should; + const cachedConstructor = cachedRes._id.constructor.name.should; + originalConstructor.should.deepEqual(cachedConstructor); + }); + + it('should return similar _id in cached array result for aggregate', async () => { + const originalRes = await aggregateAll(60); + const cachedRes = await aggregateAll(60); + const originalConstructor = originalRes[0]._id.constructor.name.should; + const cachedConstructor = cachedRes[0]._id.constructor.name.should; + originalConstructor.should.deepEqual(cachedConstructor); + }); }); function getAll(ttl, cb) { @@ -373,6 +397,10 @@ function getOne(ttl, cb) { return Record.findOne({ num: { $gt: 2 } }).cache(ttl).exec(cb); } +function getOneLean(ttl, cb) { + return Record.findOne({ num: { $gt: 2 } }).lean().cache(ttl).exec(cb); +} + function getWithSkip(skip, ttl, cb) { return Record.find({}).skip(skip).cache(ttl).exec(cb); } @@ -432,6 +460,14 @@ function aggregate(ttl, cb) { .exec(cb); } +function aggregateAll(ttl, cb) { + return Record.aggregate([ + { $match: {} }, + ]) + .cache(ttl) + .exec(cb); +} + function generate(amount) { const records = []; let count = 0;