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技术团队成员。

Redis OM .NET Redis对象映射框架的更多相关文章

  1. [非专业翻译] 高性能对象映射框架 - Mapster

    [非专业翻译] 高性能对象映射框架 - Mapster 系列介绍 [非专业翻译] 是对没有中文文档进行翻译的系列博客,文章由机翻和译者自己理解构成,和原文相比有所有不通,但意思基本一致. 因个人能力有 ...

  2. C# AutoMapper:流行的对象映射框架,可减少大量硬编码,很小巧灵活,性能表现也可接受。

    AutoMapper 是一个对象-对象映射器,可以将一个对象映射到另一个对象. 官网地址:http://automapper.org/ 官方文档:https://docs.automapper.org ...

  3. 对象映射 - Mapping.Mapster

    前言 在项目中我们会经常遇到对象的映射,比如像Model和Dto之间的映射,或者是对象的深拷贝,这些都是需要我们自己实现的.此时,项目中会出现很多初始化对象的代码,这些代码写起来相当的枯燥乏味,那么有 ...

  4. 《闲扯Redis十一》Redis 有序集合对象底层实现

    一.前言 Redis 提供了5种数据类型:String(字符串).Hash(哈希).List(列表).Set(集合).Zset(有序集合),理解每种数据类型的特点对于redis的开发和运维非常重要. ...

  5. Hibernate(开放源代码的对象关系映射框架)

    Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自 ...

  6. android对象关系映射框架ormlite之一对多(OneToMany)

    前两天,用ormlite对单张表进行了基本的操作,但是,我们知道通常情况对于单张表格进行操作在实际情况中很前两天不现实,那么ormlite能否像Hibenate那样实现多张表之间的一对多,多对多(即O ...

  7. Android数据库框架——GreenDao轻量级的对象关系映射框架,永久告别sqlite

    Android数据库框架--GreenDao轻量级的对象关系映射框架,永久告别sqlite 前不久,我在写了ORMLite这个框架的博文 Android数据库框架--ORMLite轻量级的对象关系映射 ...

  8. 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之十三 || DTOs 对象映射使用,项目部署Windows+Linux完整版

    更新 很多小伙伴在用 IIS 发布的时候,总是会有一些问题,文章下边 #autoid-6-0-0 我也简单的动图展示了,如何 publish 到 IIS 的过程,如果你能看懂,却发现自己的项目有问题的 ...

  9. redis 系列15 数据对象的(类型检查,内存回收,对象共享)和数据库切换

    一.  概述 对于前面的五章中,已清楚了数据对象的类型以及命令实现,其实还有一种数据对象为HyperLogLog,以后需要用到再了解.下面再了解类型检查,内存回收,对象共享,对象的空转时长. 1.1 ...

随机推荐

  1. 商城项目的购物车模块的实现------通过session实现

    1.新建购物车的实体类Cart public class Cart implements java.io.Serializable{ private Shangpin shangpin;//存放商品实 ...

  2. 关于tensorflow无法使用gpu

    python3.6 无法使用tensorflow gpu 环境名称 test1 在控制台里进入环境 conda activate test1 使用python python 查看gpu能否使用 pri ...

  3. 剖析虚幻渲染体系(13)- RHI补充篇:现代图形API之奥义与指南

    目录 13.1 本篇概述 13.1.1 本篇内容 13.1.2 概念总览 13.1.3 现代图形API特点 13.2 设备上下文 13.2.1 启动流程 13.2.2 Device 13.2.3 Sw ...

  4. 使用MyBatis框架时发现的一些小bug

    在大配置MyBatis.xml中:  不能有空节点属性 ,否则启动服务器后点击登录没有反应. 异常问题: ause: java.sql.SQLException: Value '0000-00-00 ...

  5. 【antd】form表单默认值设置

    问题: 在antd的form表单的api里面有个"initialValues"可以设置默认值.但是表单没有更新 <Form name="test" for ...

  6. Apache Log4j2,RASP 防御优势及原理

    Apache Log4j2 远程代码执行漏洞已爆发一周,安全厂商提供各类防御方案和检测工具,甲方团队连夜应急. 影响持续至今,网上流传的各种利用和绕过姿势还在层出不穷,影响面持续扩大.所有安全人都开始 ...

  7. [BUUCTF]PWN——[BJDCTF 2nd]test

    [BJDCTF 2nd]test 步骤 根据题目,ssh连接一下靶机 登录成功后,ls看一下当前目录下的文件,根据提示可知,我们没法直接获取flag字符串,但是我们可以读取test的源码, test. ...

  8. spring security oauth2搭建resource-server demo及token改造成JWT令牌

    我们在上文讲了如何在spring security的环境中搭建基于oauth2协议的认证中心demo:https://www.cnblogs.com/process-h/p/15688971.html ...

  9. GBK 和 UTF8

    首先来看一下常用的编码有哪些,截图自Notepad++.其中ANSI在中国大陆即为GBK(以前是GB2312),最常用的是 GBK 和 UTF8无BOM 编码格式.后面三个都是有BOM头的文本格式,U ...

  10. 快速上手FastJSON

    前言 作为一名后端开发而言肯定会接触数据,把数据提供给前端或者把数据存储起来,目前比较火热的传输格式是json,给前端传json是再常见不过啦,甚至是往db里面直接存入json. 在java层面来说j ...