我正在学习一个教程,并创建了一个cache.js文件,该文件接受 Mongoose 查询,并通过JSON.stringification将其转换为该查询返回的值的键。目标是将其缓存,然后在.cache()所在的app.js内附加mongoose.find()
当前,如果缓存为空,则让它从数据库执行GET,然后将其存储在缓存中。我有一个

console.log("CACHE VALUE #2");
console.log(cacheValue1);

这样可以确保存储数据并成功输出数据。这条线有效。但是有了这条线,
console.log("CACHE VALUE #1");
console.log(cacheValue);
cacheValue为空。

这是为什么?

它在底部存储值,并且密钥从不更改,因此我不明白为什么它不返回数据而不是null。

因此,Cache Value #1始终为空,并且Cache Value #2具有正确的数据。

控制台输出:
GRABBING FROM DB
CLIENT CONNECTION STATUS: true
Setting CACHE to True
ABOUT TO RUN A QUERY
{"$and":[{"auctionType":{"$eq":"publicAuction"}},{"auctionEndDateTime":{"$gte":1582903244869}},{"blacklistGroup":{"$ne":"5e52cca7180a7605ac94648f"}},{"startTime":{"$lte":1582903244869}}],"collection":"listings"}
CACHE VALUE #1
null
CACHE VALUE #2
(THIS IS WHERE ALL MY DATA SHOWS UP)
const mongoose = require('mongoose');
const redis = require('redis');
const util = require('util');
var env = require("dotenv").config({ path: './.env' });

const client = redis.createClient(6380, process.env.REDISCACHEHOSTNAME + '.redis.cache.windows.net', {
  auth_pass: process.env.REDISCACHEKEY,
  tls: { servername: process.env.REDISCACHEHOSTNAME + '.redis.cache.windows.net' }
});


client.get = util.promisify(client.get);


const exec = mongoose.Query.prototype.exec;

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")
    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);
    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);
      return 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);

    let redisData = JSON.stringify(result);
    //stores the mongoose query result in redis



    await client.set(key, JSON.stringify(redisData)), function (err) {
      console.error(err);

    }
    const cacheValue1 = await client.get(key);
    console.log("CACHE VALUE #2");
    console.log(cacheValue1);




    return result;
  }


最佳答案

根据您链接的pastebin,您的查询使用Date.now()作为其值。这意味着每次运行查询时,时间戳记的值都不同。

因为您的键是实际的查询,并且查询具有基于Date.now()的动态值,所以您的键永远不会相同,这就是为什么以后无法在缓存中找到它们的原因,每个查询都会生成一个唯一的键,因为Date.now()的动态值。

08-19 16:14
查看更多