学习

聚合 是一种将文档分组在一起并在服务器上运行处理以将其转换为应用程序中所需数据的方法,而无需在客户端执行计算。

管道的解剖#

Redis 中的聚合围绕聚合管道构建,您将从一个 RedisAggregationSet<T> 开始,其中包含您已在 Redis 中索引的对象。从那里您可以

  • 查询以过滤所需的結果
  • 对它们应用函数以将函数组合起来
  • 将类似的特征分组在一起
  • 对组运行缩减
  • 对记录进行排序
  • 进一步过滤记录

聚合设置#

Redis OM .NET 提供了一个 RedisAggregationSet<T> 类,它允许您对员工执行聚合,让我们从一个简单的聚合开始。让我们从定义一个模型开始:

[Document]
public class Employee
{
    [Indexed]
    public string Name { get; set; }

    [Indexed]
    public GeoLoc? HomeLoc { get; set; }

    [Indexed(Aggregatable = true)]
    public int Age { get; set; }

    [Indexed(Aggregatable = true)]
    public double Sales { get; set; }

    [Indexed(Aggregatable = true)]
    public double SalesAdjustment { get; set; }

    [Searchable(Aggregatable = true)]
    public string Department { get; set; }
}

然后,我们将为该模型创建索引,从我们的提供者中提取一个 RedisAggregationSet<T> ,初始化索引,并将一些数据播种到我们的数据库中

var provider = new RedisConnectionProvider("redis://localhost:6379");
await provider.Connection.CreateIndexAsync(typeof(Restaurant));
var employees = provider.RedisCollection<Employee>();
var employeeAggregations = provider.AggregationSet<Employee>();
var e1 = new Employee {Name = "Bob", Age = 35, Sales = 100000, SalesAdjustment = 1.5,  Department = "EMEA Sales"};
var e2 = new Employee {Name = "Alice", Age = 52, Sales = 300000, SalesAdjustment = 1.02, Department = "Partner Sales"};
var e3 = new Employee {Name = "Marcus", Age = 42, Sales = 250000, SalesAdjustment = 1.1, Department = "NA Sales"};
var e4 = new Employee {Name = "Susan", Age = 27, Sales = 200000, SalesAdjustment = .95, Department = "EMEA Sales"};
var e5 = new Employee {Name = "John", Age = 38, Sales = 275000, SalesAdjustment = .9, Department = "APAC Sales"};
var e6 = new Employee {Name = "Theresa", Age = 30, Department = "EMEA Ops"};
employees.Insert(e1);
employees.Insert(e2);
employees.Insert(e3);
employees.Insert(e4);
employees.Insert(e5);
employees.Insert(e6);

AggregationResult#

聚合管道完全围绕 RedisAggregationSet<T> 构建,此 Set 是泛型的,因此您可以提供想要围绕其构建聚合的模型(一个索引类型),但您会注意到从对 RedisAggregationSet 的查询返回的类型是传递给它的泛型类型。相反,它是一个 AggregationResult<T>,其中 T 是您传递给它的泛型类型。这是一个非常重要的概念,当结果从聚合返回时,它们不会像查询那样被水化为对象。这是因为聚合并非旨在从数据库中提取模型数据,而是旨在提取聚合结果。AggregationResult 具有一个 RecordShell 字段,该字段在管道外部始终为 null。它可用于构建用于查询 Redis 中对象的表达式,但当 AggregationResult 着陆时,它将不包含水化的记录,而是包含由聚合管道构建的聚合字典。这意味着您可以通过索引到 AggregationResult 中来访问聚合的结果。

简单聚合#

让我们尝试运行一个聚合,其中我们找到 EMEA 所有员工的销售额总和。因此,聚合管道将使用 RecordShell 对象,它是对聚合集的泛型类型的引用,对于像无分组 SUM 这样简单的事情,您将从聚合中获得一个数值类型。

var sumOfSalesEmea = employeeAggregations.Where(x => x.RecordShell.Department == "EMEA")
    .Sum(x => x.RecordShell.Sales);
Console.WriteLine($"EMEA sold:{sumOfSalesEmea}");

The Where 表达式告诉聚合管道要考虑哪些记录,随后 SUM 表达式指示要对哪个字段求和。聚合是一个丰富的功能,这仅仅触及了它的表面,这些管道非常灵活,让您能够对 Redis 中的数据执行各种巧妙的操作。

最后更新时间 2024 年 2 月 19 日