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(文档站点在布局中,会缓缓欠缺起来):
MASA.BuildingBlocks
MASA.Contrib
MASA.Utils
MASA.EShop
BlazorComponent
MASA.Blazor
QQ群:7424099
微信群:加技术经营微信(MasaStackTechOps),备注来意,邀请进群
------ END ------
作者简介
马跃:MASA技术团队成员。