Skip to content

Instantly share code, notes, and snippets.

@mstaicu
Created July 21, 2024 17:11
Show Gist options
  • Save mstaicu/55b94728cdc9590c88f718bd7122770e to your computer and use it in GitHub Desktop.
Save mstaicu/55b94728cdc9590c88f718bd7122770e to your computer and use it in GitHub Desktop.
Mongoose Redis cache functional mixin
/**
* Usage:
*
import mongoose from "mongoose";
import cacheMixin from "./cacheMixin.js";
withRedisCache(redis, mongoose.Query.prototype);
After that, any model can call .cache({ key: userId }); to enable caching
*/
function withRedisCache(client, o) {
function cache(options = {}) {
this.useCache = true;
/**
* Make sure the key is always a string
*/
this.hashKey = JSON.stringify(options.key || "");
/**
* Return this for further method chaining
*/
return this;
}
var exec = o.exec;
async function patchedExec() {
if (!this.useCache) {
return await exec.apply(this, arguments);
}
var key = JSON.stringify(
Object.assign({}, this.getQuery(), {
collection: this.mongooseCollection.name,
})
);
var cached = await client.hget(this.hashKey, key);
if (cached) {
var cachedDoc = JSON.parse(cached);
return Array.isArray(cachedDoc)
? cachedDoc.map((doc) => new this.model(doc))
: new this.model(cachedDoc);
}
var result = await exec.apply(this, arguments);
client.hset(this.hashKey, key, JSON.stringify(result));
return result;
}
return Object.assign(o, {
cache,
exec: patchedExec,
});
}
export { withRedisCache };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment