结合使用RediSearch和NRediSearchC#,如何在两个数字字段如i.CountyId == id ||上应用OR子句i.CityId == id

问题描述

我正在使用Redisearch开发一个.Net Core网络应用。以前,我曾使用过应用内内存缓存,但必须将其更改为分布式缓存。问题是,Web应用程序具有非常复杂的搜索,必须从缓存中进行处理。尽管我只是将缓存移至Redis,但必须过滤Linq才能保持与应用内内存缓存相同,但是如果Redis中有500K +条目,请在同一主机花了大约4秒钟的时间才将这些条目加载到变量中,所以这不是一个选择。

我现在已经用Redisearch实现了NRedisearch,这似乎可以很好地处理负载。我现在遇到的问题是,我在搜索中包含多个位置字段。

示例

class Item{
    public int Id {get;set;}
    public int CountyId {get;set;}
    public int CityId {get;set;}
}
class Location{
    public int LocationId {get;set;}
    public bool IsCounty {get;set;}
}

我需要将以下Linq命令转换为Redisearch

public List<Item> Search(List<Location> location){
    var result = items.Where(i => location.Any(l => l.IsCounty && l.Id == i.CountyId) || location.Any(l => !l.IsCounty && i.CityId == l.Id))
}

我已阅读Redisearch文档,但尚未找到任何答案。由于排序,我必须在一次搜索中执行此操作。

解决方法

我发现他回答了。

FT.SEARCH idx "@title|body:(hello world) @url|image:mydomain"

如果NRediSearch可以在新查询中处理此操作符或操作符,如果不能,则必须直接通过其客户端来实现

,

您可以使用我通过nredisearch建立的图书馆。但它适用于简单的linq查询。它不适用于嵌套对象。如果您为它的发展做出了贡献,我将感到高兴。

如果我们谈论您的示例,您必须像这样复制每个位置的数据:

class Item {

    public int Id {get;set;}
    public int CountyId {get;set;}
    public int CityId {get;set;}
    public int LocationId {get;set;}
    public bool IsCounty {get;set;}
}

您可以在我的图书馆中搜索此daha。

RedisworkCore

PackageManager:

Install-Package RedisworkCore

Dotnet CLI:

dotnet add package RedisworkCore

,您可以创建诸如entityframework之类的上下文:

public class Person
{
    [RedisKey(0)]
    public int Id { get; set; }
    public string Name { get; set; }
    public string Lastname { get; set; }
}

public class SimpleContext : RedisContext
{
    public Rediset<Person> Persons { get; set; }
    public SimpleContext(RedisContextOptions options) : base(options) { }
}

然后,您可以使用“查找”,“位置”,“任意”,“全部”,“按排序”,“按降序排序”,“跳过”,“采用类似的LINQ”。

static async Task Main(string[] args)
{

  RedisContextOptions options = new RedisContextOptions
  {
    HostAndPort = "localhost:6379"
  };

  using (var context = new SimpleContext(options))
  {
    var person = new Person
    {
      Id = 26,Name = "Emre",Lastname = "Hızlı"
    };
    context.Persons.Add(person);
    await context.SaveChangesAsync();
  }

  using (var context = new SimpleContext(options))
  {
    Person person = await context.Persons.Find(26);
    List<Person> persons = await context.Persons.Where(x => x.Id > 0).ToListAsync();
  }
  
}

注意:

  • 您应该使用redisworkcore保存数据,否则它将无法正常工作。
  • 未进行性能测试。如果我可以作为开源获得支持,那可能会更好。