当前位置: 首页 > 软件库 > 大数据 > 数据查询 >

mongoose-plugin-cache

The Perfect Marriage of MongoDB and Redis
授权协议 MIT License
开发语言 Java
所属分类 大数据、 数据查询
软件类型 开源软件
地区 不详
投 递 者 陈文景
操作系统 跨平台
开源组织
适用人群 未知
 软件概览

mongoose-plugin-cache

Seamlessly boost your MongoDB performance with Redis

Why mongoose-plugin-cache?

  • Performance: Significantly enhance the overall User Experience by resolving the data from memory.
  • Efficiency: Cache with peace of mind. It handles the cache synchronization with Mongoose create, findByIdAndUpdate, findOneAndUpdate, findByIdAndDelete and findOneAndDelete hooks, so you don't have to.
  • Flexible: Enable only the model you want to cache as well as specifying the additional cache keys to resolve.

Prerequisite: Mongoose 5. One of the biggest updates from Mongoose 4 to 5 is the synchronous and stability of hook, which helps get the data in sync easily.

Installation

yarn add mongoose-plugin-cache

Getting Started

import mongoose from 'mongoose'
import createCachePlugin from 'mongoose-plugin-cache'
import redis from './redis'

const schema = new mongoose.Schema({
  name: String,
  email: String,
})

schema.plugin(
  createCachePlugin({
    // your own node_redis instance
    // keep all your preferences like cache prefix, caching strategy, and global promise to be used
    redis,
    // it will use Redis only if you enable it (default: false),
    // and you may only want to enable for the model with high frequency database access
    enable: true,
  }),
)

const User = mongoose.model('User', schema)

Basic Usage

Resolving from Cache

It first tries to resolve the value from the cache by a given ID. If it hits the cache, the value will be returned directly from Redis. If it does not hit the cache, it will resolve the data from the database and set it into Redis, onCacheMiss will be called. If there is no such data, onDataMiss hook will be called.

With Mongoose only, we normally do:

const user = await User.findById('<userId>')

Instead of using findById or findOne, an extra methods get is provided for cache retrieval:

const user = await User.get('<userId>')

Batch Operation

It performs the same cache resolve logic, but the responses will always match their corresponding ID index location and resolves it with null if there is no data from the Database. It also runs data retrieval for those who have cache miss in batch to reduce the IO operation.

With Mongoose only, we do:

const userIds = ['<userId1>', '<userId2>']

const users = await User.find({
  _id: {
    $in: userIds,
  },
})

An extra method getMany is provided for batch cache retrieval:

const users = await User.getMany(userIds)

Clearing the Cache

Clearing the cache will only remove the matching cache in Redis. The data in the database is not affected.

await User.clear('<userId>')
await User.clearMany(['<userId1>', '<userId2>', '<slug1>', '<slug2>'])

Advance Usage

Additional Cache Keys

Sometimes we might use fields other than _id to resolve the data. For instance, username and email are often considered unique in a User model. Plus, for security reason, the client application normally does not manipulate the ID directly. Instead of mapping the actual ID to a particular field, you can provide an option called additionalCacheKeys to the plugin, and it will add an index to MongoDB and map it with the corresponding _id for the resolve.

schema.plugin(
  createCachePlugin({
    ...options,
    additionalCacheKeys: ['slug'],
  }),
)

const Entry = mongoose.model('Entry', schema)

// getBy with an extra param is equivalent to getBySlug
await Entry.getBy('slug', '<slug>')
await Entry.getBySlug('<slug>')

// it also supports batching
await Entry.getBySlug(['<slug1>', '<slug2>'])
await Entry.getBySlugs(['<slug1>', '<slug2>'])

Metrics

Sometimes, you may want to be notified when there is a cache miss or data miss event to strengthen the control over the data.

schema.plugin(
  createCachePlugin({
    ...options,
    onCacheMiss: (modelName: string, key: string) => {
      console.log(`cache_miss.${modelName}.${key}`)
    },
    onDataMiss: (modelName: string, key: string) => {
      console.log(`cache_data_miss.${modelName}.${key}`)
    },
  }),
)

Using with Dataloader and GraphQL

mongoose-plugin-cache works perfectly with Dataloader and GraphQL. It is encouraged to create a new DataLoader per request and combines it with the shared cache compatibility with mongoose-plugin-cache to further reduce the number of database access.

import Dataloader from 'dataloader'
const userLoader = new DataLoader(ids => User.getMany(ids))

And call it with:

await userLoader.load('<userId>')

With GraphQL's field resolver, you don't even have to use Mongoose's .populate() with better Separation of Concern.

Consider the following Mongoose schema design:

{
  ...userFields,
  authorId: { type: Schema.Types.ObjectId, ref: 'User' }
}

And the following GraphQL type definition:

type Entry {
  id: ID!
  slug: ID!
  title: String
  author: User
}

We can resolve the actual User using GraphQL field resolver with the combination with Dataloader:

{
  author: ({authorId}, _, {userLoader}) => userLoader.load(authorId),
}

Testing

yarn test

Related Projects

Contributing

Please read CONTRIBUTING.md for details, and feel free to submit pull requests to us.

  • 是不是语法有问题 我在我本地的mongdb 4.0.26 node.js 可以创建账号Bibooo 跟加密的密码 const mongoose = require("./db"); const LoginState = new mongoose.Schema({ username: {type:String,unique:true}, passwrod: { type: String, //加密

  • 报错模型未注册。 示例 const Goods = require('../../model/admin/Goods');//先引入你需要的关联模型 const res = await ctx.mongoose.find().populate({ path: 'Goods ', model: Goods }).limit(10);//在这里使用Goods 就是你引入的模型,我的理解就是告诉他该往

  • mongoose 的CRUD -C creat: 模型对象.create(文档对象,回调函数) 模型对象.create(文档对象) -R Read: 模型对象.find(查询条件,[投影]) 注意⚠️:不管有没有数据,都返回一个数组 模型对象.findOne(查询条件,投影]) 注意⚠️:找到了返回一个对象,没找到返回数组 -U update 模型对象.updateOne(查询条件,要更新的内容,

  • 一、mongoose 索引 完整例子 const mongoose = require('./db'); const UserSchema = mongoose.Schema({ name: String, age: Number, sn: { type: String, index: true } }) module.expor

  • 扩展静态方法 定义Schema let HeroSchema = new mongoose.Schema({ // 此处为表字段内容 }); 定义静态方法 // 自定义查询方法 HeroSchema.statics.findByType = function (type, callback) { // this关键字可以获取当前model this.find({ type: ty

  • 一、Mongoose简介  Mongoose是一个让我们可以通过Node来操作MongoDB的模块,是一个对象文档模型(ODM),它对Node原生的MongoDB模块进行了进一步的优化封装,并提供了更多的功能。大多数情况下,Mongoose被用来把结构化的模式应用到一个MongoDB集合,并提供验证和类型转换等。简单的说它是前端开发用来操作MongoDB的一个工具,类似于后台开发使用Mybatis

  • 一,npm安装mongoose模块 npm install mongoose --save 二,连接mongodb数据库 //mongodb://协议+/ip地址+端口号+/数据库名 mongoose.connect("数据库的url地址/mongodb://loacalhost/my_db"); //创建mongoose实例对象 const db = mongoose.connection;

  • 首先来看个例子: 通常的处理办法 // format date topic.friendly_create_at = tools.formatDate(topic.create_at, true); topic.friendly_update_at = tools.formatDate(topic.update_at, true); 还有 user.friendly_create_at = too

  • 首先在项目的根路径下面添加几个重要的文件夹,分别为: config -> db.js -> 存放数据库连接信息,以及连接数据时成功以及报错消息. model -> dbModel.js -> 数据库中的模型 dao -> dbServer.js -> 对数据库中的集合进行增删改查 server -> 待续… 实现操作数据库的步骤 1.db.js 先配置连接数据库,然后编辑连接成功、失败的消息 co

 相关资料
  • mongoose-history-plugin Mongoose plugin that saves documents history in JsonPatch format and SemVer format. Table of Contents Features Install Use Document Methods document.getDiffs(findQuery) documen

  • Mongoose 是设计用于异步环境的 MongoDB 对象模型工具,支持 promises 和 callbacks。 概述 连接到 MongoDB 首先需要定义一个连接。如果应用仅使用一个数据库,则使用mongoose.connect。如果需要创建其他连接,请使用mongoose.createConnection。 connect 和 createConnection都使用 mongodb://

  • 问题内容: 据我所知,方法是,那是,并且也喜欢,但它们不是存储在数据库中。 但是,我想知道那是和之间的唯一区别。还有其他我想念的东西吗? 问题答案: 实例方法,静态方法或虚拟方法均未存储在数据库中。方法与虚拟函数之间的区别在于,虚拟函数的访问方式类似于属性,方法的调用方式类似于函数。实例与静态实例与虚拟实例之间没有区别,因为在类上具有可访问的虚拟静态属性是没有意义的,但在类上具有某些静态实用程序或

  • Mongoose Web Server是一款易于使用的Web服务器,它可以嵌入到其它应用程序中,为其提供Web接口。 主要特写: 跨平台,支持 Windows、OS X 和 Linux 支持 CGI, SSL, SSI, Digest (MD5) 认证,WebSocket 和 WebDAV 支持断点续传和 URL 重写 基于 IP 的 ACL,支持 Windows 服务,支持 GET, POST,

  • Mongoose OS 是一个物联网固件开发框架。支持的微控制器包括 ESP32、ESP8266、CC3220、CC3200、STM32F4、STM32L4 与 STM32F7。集成了 Amazon AWS IoT、Microsoft Azure 与 Google IoT Core。 特性: 固件热更新和远程管理,可靠的更新能力,包括故障回滚、远程设备访问基础架构 安全性,内置闪存加密,支持加密芯

  • mongoose-tsgen A plug-n-play Typescript generator for Mongoose. Motivation Features Compatibility Installation The Gist Usage Example Development Motivation Using Mongoose with Typescript requires dup