【问题标题】:Is there a way to cancel mongoose find execution and return data from redis instead?有没有办法取消猫鼬查找执行并从redis返回数据?
【发布时间】:2021-02-12 08:22:56
【问题描述】:

我正在尝试在 nest.js 中实现 Redis 缓存和 mongoose,我正在寻找一种方法 在执行 find 或 findOne 之前先检查 redis 缓存并从 redis 返回数据 否则执行查询,将结果保存在redis中并返回结果。 我没有按照nest.js 的建议实施caching 的原因 是我也在使用 Apollo Server for GraphQL。

@Injectable()
export class MyService {
    async getItem(where): Promise<ItemModel> {
        const fromCache = await this.cacheService.getValue('itemId');
        if(!!fromCache){
            return JSON.parse(fromCache);
        } else {
            const response = await this.ItemModel.find(where);
            this.cacheService.setValue('itemId', JSON.stringify(response));
            return response
        }
    }
}

我想将这段代码移动到一个地方,这样我就不必 因为我有多个服务,所以对我的代码中的每个查询重复此代码。 我知道 mongoose 中间件可以在查询中运行 pre 和 post 函数 但我只是不确定如何使用。

这些是我正在使用的版本:

  • nestjs v7
  • 猫鼬 v5.10.0

【问题讨论】:

  • 请详细说明您无法使用 Apollo 的默认缓存设置的原因。我看不出有什么理由不能一起使用它们。就本机 NestJS 功能而言,拦截器可能是您以可重用方式实现此类模式的最佳选择
  • nestjs 文档中解释的默认缓存在控制器级别工作,我想要完成的是与 mongoose 一起缓存,以便每次在我的 mongo 数据库中插入/更新新记录时我都可以清除缓存.在文档中指出缓存不能与 GraphQL 一起正常工作 [“在 GraphQL 应用程序中,拦截器是为每个字段解析器单独执行的。因此,CacheModule(它使用拦截器来缓存响应)将无法正常工作。”]docs.nestjs.com/techniques/caching#in-memory-cache>

标签: typescript mongoose redis nestjs


【解决方案1】:

您可以创建一个method decorator,将逻辑移至:

export const UseCache = (cacheKey:string) => (_target: any, _field: string, descriptor: TypedPropertyDescriptor<any>) => {
    const originalMethod = descriptor.value;
    // note: important to use non-arrow function here to preserve this-context
    descriptor.value     = async function(...args: any[]) {
        const fromCache = await this.cacheService.getValue(cacheKey);
        if(!!fromCache){
            return JSON.parse(fromCache);
        }
        const result = await originalMethod.apply(this, args);
        await this.cacheService.setValue(cacheKey, JSON.stringify(result));
        return result;
    };
}

然后使用它:

@Injectable()
export class MyService {   

    constructor(private readonly cacheService:CacheService) { .. }

    @UseCache('itemId')
    async getItem(where): Promise<ItemModel> {        
        return this.ItemModel.find(where);
    }

    @UseCache('anotherCacheKey')
    async anotherMethodWithCache(): Promise<any> {        
         // ...            
    }
}

【讨论】:

    猜你喜欢
    • 2021-08-04
    • 2018-11-28
    • 2021-05-25
    • 2016-11-14
    • 2020-02-28
    • 2018-07-12
    • 2017-06-06
    • 2020-09-23
    • 2019-10-04
    相关资源
    最近更新 更多