简体   繁体   中英

nodejs-express - Implement Redis caching over main database as mongodb

I have a simple API with basic CRUD operations where a User can have multiple Tasks and once user logged in can Update, Delete, Add and Fetch all the tasks. I am using MongoDB with mLab as my main data store to store documents for User and Task Schemas. I want to implement Redis caching in my app(Just for learning purposes) and a use case I can think of is to implement it when I fetch tasks for a particular user(on Homepage) when he logs in as that getAllUserTasks is very often used and called when there is any Delete/Update/Add happens. As of now, the app works fine with MongoDB and documents are getting properly reflected in mLab . Now coming to Redis part, I have a query that how should I structure my Redis Database. First, let me post what I have in my App so far :

User Schema :

const userSchema = new Schema({
  userName: { type: String, unique: true, required: true },
  hashPassword: { type: String, required: true },
  firstName: { type: String, required: true },
  lastName: { type: String, required: true },
  userAge: { type: Number, required: true },
  userDetails: { type: String, required: true },
  userCreatedOn: { type: Date, default: Date.now }
});

Task Schema :

const taskSchema = new Schema({
  //Below is userAssigned which is ref for above User document.
  userAssigned: { type: Schema.Types.ObjectId, ref: User},
  taskDesc: { type: String, required: true },
  taskCreatedOn: { type: Date, default: Date.now },
  taskDueDate: { type: Date, required: true }
});

getAllUserTasks function:

async function getAllUserTasks(userParam) {
  return await Task.find({ userAssigned: userParam.userId })
    .lean()
    .sort({ taskDueDate: "asc" });
}

Now getAllUserTasks returns me an Array of all the tasks for the User. I googled a bit and found that I can use https://redislabs.com/ for my Redis Database. Now how should I structure my Redis database to fetch tasks performantly? 1. Should I just copy the above schema to Redis database and my tasks documents will live over there. 2. Should I have a key like 'Tasks' and a value will be an Array of Tasks that I am getting from .find in the getAllUserTasks call. If that's the case how will I make sure that once tasks are Deleted/Updated/Added the Redis Database will be updated accordingly? Just for reference below are my Update/Create/Delete methods :

createTask

async function createTask(userParam) {
  if (await User.findOne({ _id: userParam.userAssigned })) {
    const task = new Task(userParam);
    await task.save();
  } else {
    throw "User does not exist";
  }
}

updateTask

async function updateTask(id, userParam) {
  return await Task.findOneAndUpdate(
    { _id: id },
    userParam,
    {
      new: true,
      overwrite: true
    },
    function(err) {
      if (err) return err;
    }
  );
}

deleteUserTask

async function deleteUserTask(id) {
  return await Task.findByIdAndRemove(id, function(err) {
    if (err) {
      return err;
    }
  });
}

As I am new to Redis any help would be really appreciated. Thanks!

You dont have to store all data to redis. Cache is kind of shortcut. It is good if there is a data, but it does not matter if there is not.

Store tasks when getAllUserTasks is called. Key can be user id. Value can be array of task having id for identity.

If someone's tasks are mutated, just clear someone's tasks from redis.

getAllUserTasks(param) {
  1. Find tasks from redis by user key.
  2. If they exist, return them.
  3. If not, get data from db and store them to redis.
  4. Return data.
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM