Redis won't retrieve data from cache Redis won't retrieve data from cache mongoose mongoose

Redis won't retrieve data from cache


Based on the pastebin you linked, your queries are using Date.now() for their values. This means that each time a query is run, you have different values for the timestamp.

Because your keys are the actual query, and the query has dynamic values based on Date.now(), your keys will never be the same, which is why you can't find them in the cache later, each query is generating a unique key because of the dynamic values of Date.now().


I reproduced your code within a minimal example and I got it working as you wanted.It serves the response from the redis cache after the first request. I just logged values and found some small mistakes in your code,you will easily spot them(calling this.model with the doc, fix the set and remove the last get for the redis client). I don't think that this is the best way to cache responses because you set a variable to true in every request and also you reach to mongo and mongoose before you use cache.With a middleware all this can be prevented and you will take away some more ms but still its not the worst way either so here is my minimal working example.

const http = require('http')const mongoose = require('mongoose')const redis = require('redis')const port = 3000;const util = require('util');const client = redis.createClient()client.get = util.promisify(client.get);mongoose.connect('mongodb://localhost:27017/testdb', {useNewUrlParser: true});const exec = mongoose.Query.prototype.exec;  var Schema = mongoose.Schema;  var testSchema = new Schema({    testfield:  String, // String is shorthand for {type: String}  }); var Test = mongoose.model('Test', testSchema);mongoose.Query.prototype.cache = function() {  this.useCache = true;  console.log("Setting CACHE to True")  return this;}mongoose.Query  .prototype.exec = async function () {    if (!this.useCache) {      console.log("GRABBING FROM DB")      console.log("CLIENT CONNECTION STATUS: " + client.connected);      return exec.apply(this, arguments);    }    console.log("ABOUT TO RUN A QUERY")      console.log("Query ==", this.getQuery())      console.log("Collection == ", this.mongooseCollection.name);    const key = JSON.stringify(Object.assign({}, this.getQuery(), {      collection: this.mongooseCollection.name    }));    //See if we have a value for 'key' in redis    console.log("KEY FROM QUERY AND COLLECTION",key);    const cacheValue = await client.get(key);    console.log("CACHE VALUE #1");    console.log(cacheValue);    //If we do, return that    if (cacheValue) {      console.log("cacheValue IS TRUE");      const doc = JSON.parse(cacheValue);        console.log("DOC == ",doc);      return Array.isArray(doc)        ? doc.map(d => d)        : doc           // return exec( Array.isArray(doc)       // ? doc.map(d => new this.model(d))        //: new this.model(doc))    }    //Otherwise, issue the query and store the result in redis    const result = await exec.apply(this, arguments);   // console.log("EXEC === ", exec);   // console.log("result from query == ", result);    let redisData = JSON.stringify(result);    //stores the mongoose query result in redis    console.log("REDis data ===", redisData);    await client.set(key, redisData, function (err) {      console.error(err);    })    return result;  }const server = http.createServer(function(req, res) {    if(req.url === '/'){        Test.find({}).cache().exec().then(function( docs) {          console.log("DOCS in response == ", docs);          res.writeHead(200, { 'Content-Type': 'text/plain' });          res.end(JSON.stringify(docs))        })    }})server.listen(port, function() {    console.log(`Server listening on port ${port}`) })