Redis OM .NET Redis对象映射框架
Redis OM
Redis OM 是 Redis 官方推出的对象映射框架,即:Object Mapping。让开发人员更简单、方便的操作 Redis 数据。Redis 存储的数据抽象为对象映射,支持基于对象的 Redis 数据持久化、流式查询操作。
目前只支持 4 种开发语言:
- Redis OM for Spring
- Redis OM for .NET
- Redis OM for Node.js
- Redis OM for Python
Redis OM .NET
Redis OM .NET 是.Net 平台的 Redis OM,依赖 StackExchange.Redis 实现。借助 Redis OM .NET 可以实现对象操作的方式操作 Redis 数据,脱离 key/value 的操作方式。
查询支持大部分.Neter 最爱的 LINQ。
快速开始
安装对应包
1 | dotnet add package Redis.OM |
Redis 环境准备
直接使用 Docker 的方式安装 Redis 环境。
1 | docker run -p 6379:6379 redislabs/redismod:preview |
标准的官方镜像是无法支持 Redis OM,需要 Redis Modules 支持,Redis OM 核心创建索引、查询数据依赖
RediSearch
这个 Module 实现。依赖的 Module 有:RediSearch、RedisJSON。
RedisJSON 的依赖不是必须的,但是会缺少相应的功能,如:模型嵌套、复杂查询(只支持 key 查询)
Coding
增加抽象对象定义
1 | [ ] |
Document、Indexed、Searchable 等特性介绍,介绍参考 Github -> document-attribute
获取抽象对象的操作集合、创建索引
1 | var provider = new RedisConnectionProvider("redis://localhost:6377"); |
查询数据、聚合操作等需要依据索引,所以一定要先调用connection.CreateIndex
创建索引,对应 RediSearch 的FT.CREATE
命令。
connection.CreateIndex(typeof(Customer)) 创建索引重复执行会抛出异常
Index already exists
。虽然可以通过connection.Execute("FT.INFO", $"customer-idx")
获取索引信息,但是第一次索引不存在时会抛出Unknown Index name
。所以实际使用中可能需要一个 try-catch 包住CreateIndex
方法避免异常。
插入数据
1 | var id = customers.Insert(new Customer { FirstName = "Steve", Email = "xxxx@masa.com", Age = 1 }); |
id,id2 为插入数据的 key,没有指定 Document 的 Prefixes 和 IdGenerationStrategy,则默认为 ULID 格式为{DocumentName}:{Ulid}
,如:`Cust
插入数据时需要注意的是,如果对没有明确指定字段的值,如 LastName 不明确赋值:
customers.Insert(new Customer { FirstName = "Steve", Email = "xxxx@masa.com", Age = 1 });
,查看 Redis 中存的数据可以发现当前 key 存储的 json 数据没有未指定的字段对应的 key(此时 Query 或 Aggregations 会有些奇怪的错误)。可以根据自己需要,显示的为字段赋个零值或者在定义实体时使用public string LastName { get; set; } = string.Empty;
的方式。
查询数据
1 | var customer = customers.Where(x => x.Age == 0).OrderBy(a => a.FirstName).FirstOrDefault(); |
对于空值的判断,x.FirstName == “”【语法错误】 或 string.IsNullOrEmpty(x.FirstName)【不支持】。Redis 哈希中不能有空字符串,所以类似的查询应该通过聚合操作的Exists
方法实现
1 | foreach (var agg in customerAggregations.Apply(x => ApplyFunctions.Exists(x.RecordShell.LastName), "LastNameExists")) |
聚合操作
流水线(Pipelining)同时发送多个请求,从而减轻延迟。结果的查询和转化都在 Redis 端完成。
RecordShell 是远端 Index 类型的结构,RecordShell 应该只在聚合操作流水线内部使用,运行时并没有真正的值。
拼凑 FirstName 和 LastName,返回 FullName
1 | var customerAggregations = provider.AggregationSet<Customer>(); |
聚合分组
通过 GroupBy 方法,依据不同属性进行分组聚合(支持单字段分组和多字段分组)。
1 | var res = customerAggregations |
CloseGroup 可以关闭分组,转换为正常的聚合操作,即 GroupedAggregationSet 到 RedisAggregationSet 的一个转换。
1 | public static RedisAggregationSet<T> CloseGroup<T>(this GroupedAggregationSet<T> source) |
结尾
本文只是对 Redis OM .NET 用法的简单梳理和可用性验证。
更多用法以及用法更新参考Github
Redis OM .NET Redis对象映射框架
https://blogs.masastack.com/2021/12/02/independent/redis/redis_om_net/