Reputation: 3878
Currently I'm working on a project where we need to build our secondary indexes on top of redis. Since the actual datastore is going to be a blob database like S3/Azure Blob.
So far we are able to implement our own schema manager, Create/Update/Delete for indexes whenever data is changed. And the indexes are stored as SortedSet
in Redis
query.Where<Employee>(emp => emp.JoinedOn >= startDate
&& emp.JoinedOn <= endDate
&& emp.Salary >= 150000);
We have also implemented querying logic using the C# expression. Where we built an expression parser to go through the expression lambda and run each binary expression and combine the results.
Once we run this query we will have list of keys, which we can go and fetch from S3/Azure blob.
The Problem
Now the problem is if we want to support sorting we have to fetch the entire index data and intersect the result with the result that we got after querying.
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>());
}
Is there a way we could avoid querying the entire index to support this?
Upvotes: 0
Views: 469
Reputation: 6267
Is there a way we could avoid querying the entire index to support this?
Yes and no.
You can't achieve this using only plain Redis.
But you can (and should) consider RediSearch - Redis Secondary Index & Query Engine which is very well suited for your requirement and beyond. This is a module built on top of Redis and maintained by Redis Labs itself.
Upvotes: 1