如何使用 redis 作为二级索引提供排序功能

问题描述

目前我正在做一个项目,我们需要在 redis 之上构建二级索引。由于实际的数据存储将是一个 Blob 数据库,如 S3/Azure Blob。

到目前为止,我们能够实现我们自己的模式管理器,每当数据发生变化时为索引创建/更新/删除。并且索引在Redis中存储为SortedSet

query.Where<Employee>(emp => emp.JoinedOn >= startDate 
               && emp.JoinedOn <= endDate 
               && emp.Salary >= 150000);

我们还使用 C# 表达式实现了查询逻辑。我们构建了一个表达式解析器来遍历表达式 lambda 并运行每个二进制表达式并组合结果。

运行此查询后,我们将获得键列表,我们可以从 S3/Azure blob 中获取这些键。

问题

现在的问题是,如果我们想要支持排序,我们必须获取整个索引数据并将结果与​​我们查询后得到的结果相交。

private async Task<string[]> SortResults(QueryModel queryModel,string sortIndex,Stack<List<string>> resultStore)
        {
            var order = queryModel.sortInfo.Direction == SortDirection.Ascending
                ? Order.Ascending
                : Order.Descending;
            var sortedSet = await cacheProvider.sortedSetGetRangeByscoreAsync(sortIndex,double.NegativeInfinity,double.PositiveInfinity,Exclude.None,order);
            var ids = resultStore.Any() ? resultStore.Pop().ToArray() : null;
            return (string[]) sortedSet.Intersect(ids ?? Array.Empty<string>());
        }

有没有办法避免查询整个索引来支持这一点?

解决方法

有没有办法避免查询整个索引来支持这一点?

是和否。

仅使用普通 Redis 无法实现这一点。

但是您可以(并且应该)考虑 RediSearch - Redis Secondary Index & Query Engine,它非常适合您的要求及其他要求。这是一个建立在Redis之上的模块,由Redis Labs自己维护。