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。
快速开始
安装对应包
dotnet add package Redis.OM
Redis 环境准备
直接使用 Docker 的方式安装 Redis 环境。
docker run -p 6379:6379 redislabs/redismod:preview
标准的官方镜像是无法支持 Redis OM,需要 Redis Modules 支持,Redis OM 核心创建索引、查询数据依赖
RediSearch
这个 Module 实现。依赖的 Module 有:RediSearch、RedisJSON。 RedisJSON 的依赖不是必须的,但是会缺少相应的功能,如:模型嵌套、复杂查询(只支持 key 查询)
Coding
增加抽象对象定义
[Document] public class Customer { [RedisIdField] public string Id { get; set; } [Indexed(Sortable = true, Aggregatable = true)] public string FirstName { get; set; } [Indexed(Sortable = true, Aggregatable = true)] public string LastName { get; set; } [Indexed] public string Email { get; set; } [Indexed(Sortable = true)] public int Age { get; set; } }
Document、Indexed、Searchable 等特性介绍,介绍参考 Github -> document-attribute
获取抽象对象的操作集合、创建索引
var provider = new RedisConnectionProvider("redis://localhost:6377"); var connection = provider.Connection; var customers = provider.RedisCollection<Customer>(); connection.CreateIndex(typeof(Customer));
查询数据、聚合操作等需要依据索引,所以一定要先调用connection.CreateIndex
创建索引,对应 RediSearch 的FT.CREATE
命令。
connection.CreateIndex(typeof(Customer)) 创建索引重复执行会抛出异常
Index already exists
。虽然可以通过connection.Execute("FT.INFO", $"customer-idx")
获取索引信息,但是第一次索引不存在时会抛出Unknown Index name
。所以实际使用中可能需要一个 try-catch 包住CreateIndex
方法避免异常。
插入数据
var id = customers.Insert(new Customer { FirstName = "Steve", Email = "xxxx@masa.com", Age = 1 }); var id2 = customers.Insert(new Customer { FirstName = "FirstName", LastName = "LastName", Email = "xxxx@masa.com" });
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;
的方式。
查询数据
var customer = customers.Where(x => x.Age == 0).OrderBy(a => a.FirstName).FirstOrDefault(); var customerById = customers.FindById(id);//根据Id查找 var emails = customers.Select(x => x.Email);//仅查询指定字段 var takes = customers.Where(x => x.Age > 0).Take(10);//获取指定条数 var adults = customers.Where(x => x.Age >= 0).Skip(5);//查询偏移
对于空值的判断,x.FirstName == ""【语法错误】 或 string.IsNullOrEmpty(x.FirstName)【不支持】。Redis 哈希中不能有空字符串,所以类似的查询应该通过聚合操作的Exists
方法实现
foreach (var agg in customerAggregations.Apply(x => ApplyFunctions.Exists(x.RecordShell.LastName), "LastNameExists")) { Console.WriteLine($"{agg["LastNameExists"]}"); }
聚合操作
流水线(Pipelining)同时发送多个请求,从而减轻延迟。结果的查询和转化都在 Redis 端完成。
RecordShell 是远端 Index 类型的结构,RecordShell 应该只在聚合操作流水线内部使用,运行时并没有真正的值。
拼凑 FirstName 和 LastName,返回 FullName
var customerAggregations = provider.AggregationSet<Customer>(); var age = customerAggregations.Average(x => x.RecordShell.Age); var sets = customerAggregations.Where(a => a.RecordShell.FirstName == "Steve").Apply(x => string.Format("{0} {1}", x.RecordShell.FirstName, x.RecordShell.LastName), "FullName"); foreach (var item in sets) { Console.WriteLine(item["FullName"].ToString()); }
聚合分组
通过 GroupBy 方法,依据不同属性进行分组聚合(支持单字段分组和多字段分组)。
var res = customerAggregations .GroupBy(x => x.RecordShell.FirstName) .GroupBy(x => x.RecordShell.LastName) .ToArray(); var res1 = customerAggregations.GroupBy(x => x.RecordShell.FirstName).CloseGroup().ToArray();
CloseGroup 可以关闭分组,转换为正常的聚合操作,即 GroupedAggregationSet 到 RedisAggregationSet 的一个转换。
public static RedisAggregationSet<T> CloseGroup<T>(this GroupedAggregationSet<T> source) { return new RedisAggregationSet<T>(source, source.Expression); }
结尾
本文只是对 Redis OM .NET 用法的简单梳理和可用性验证。 更多用法以及用法更新参考Github
我们正在行动,新的框架、新的生态
我们的目标是自由的
、易用的
、可塑性强的
、功能丰富的
、健壮的
。
所以我们借鉴Building blocks的设计理念,正在做一个新的框架MASA Framework
,它有哪些特点呢?
- 原生支持Dapr,且允许将Dapr替换成传统通信方式
- 架构不限,单体应用、SOA、微服务都支持
- 支持.Net原生框架,降低学习负担,除特定领域必须引入的概念,坚持不造新轮子
- 丰富的生态支持,除了框架以外还有组件库、权限中心、配置中心、故障排查中心、报警中心等一系列产品
- 核心代码库的单元测试覆盖率90%+
- 开源、免费、社区驱动
- 还有什么?我们在等你,一起来讨论
经过几个月的生产项目实践,已完成POC,目前正在把之前的积累重构到新的开源项目中
目前源码已开始同步到Github(文档站点在规划中,会慢慢完善起来):
QQ群:7424099
微信群:加技术运营微信(MasaStackTechOps),备注来意,邀请进群
------ END ------
作者简介
**马跃:**MASA技术团队成员。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
暑期2021优秀学生专访:热衷实践的“开源老将”——张奇夫
开源软件供应链点亮计划-暑期 2021已经收官,在为期三个月的开源实践中,我们不仅收获了529个结项项目,还收获了各位参与项目的宝藏同学们。为了进一步巩固这些新生的开源力量,组委会特邀请指导委员会老师从4个方向评选出了具有代表性的20位优秀学生。 本次采访,我们邀请最佳质量奖获奖者张奇夫,分享自己的开源故事和活动感悟。 优秀学生迷你简历 姓名:张奇夫 性别:男 年龄:20岁 学校:西安电子科技大学 兴趣爱好:看动漫玩游戏 自娱自乐写一些小工具 -- 自我介绍 -- 1、首先,请简单介绍一下自己 大家好,这里是Apache553,或者在现实中被称为张奇夫。现在仍然在西安电子科技大学就读本科。主要使用的语言是c++,兴趣摇摆不定。鄙人才疏学浅,还请多多指教。 2、最开始是在哪里了解到开源的,是什么让你决定参与开源? 最开始是初中的时候想自制一个用来看小说的设备(笑),当时了解到了树莓派这一神奇的设备,就决定用树莓派来做,最后我度过了一个相对不那么无聊的初中时光。在做的过程中,由于很多相关的资料都在Github上,就逐渐了解到了开源这回事。参与的话,感觉就很顺其自然地,遇到有别人没发现过...
- 下一篇
Go 语言社区系统 BBS-GO 3.4.0 发布,支持评论盖楼模式,多处功能优化
更新内容 新增:评论盖楼模式、优化评论组件 新增:记录发帖、评论用户的 UA、IP 修复:关闭密码登录后,管理后台无法登录的问题 修复:搜索框显示问题,调整搜索框样式 修复:头像修改失败的问题 修复:修复后台几个 BUG 优化:个人资料编辑页面 优化:用户注册、登录页面样式 优化:go.mod 依赖 优化:界面样式细节 发布地址 github:https://github.com/mlogclub/bbs-go/releases/tag/v3.4.1 gitee:https://gitee.com/mlogclub/bbs-go/releases/v3.4.1 功能简介 功能预览 相关链接 帮助文档:http://docs.bbs-go.com/ 官网交流:https://mlog.club 问题反馈:https://mlog.club/topics/node/3 功能建议收集:https://mlog.club/topic/609 github 地址:https://github.com/mlogclub/bbs-go gitee 地址:https://gitee.com/mlog...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS关闭SELinux安全模块
- Linux系统CentOS6、CentOS7手动修改IP地址
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- CentOS6,CentOS7官方镜像安装Oracle11G
- CentOS7设置SWAP分区,小内存服务器的救世主