skip to Main Content

I am developing a .Net Core web app with RediSearch. Previously I have used in-app memory cache, but I have to change it to distributed cache. The issue is, the web app has very complex searches which must be handled from cache. I though I just move the cache to Redis and must filter in Linq will stay the same just as with in-app memory cache, but if you have 500K+ entries in Redis, using a docker image on the same host took around 4 sec just to load these entries into a variable so this is not an option.

I have now implemented RediSearch with NRediSearch which seem to handle the load pretty well. The issue I have now, I have a search with multiple location fields.

Example

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;}
}

I need to translate the following Linq command into 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))
}

I have read the RediSearch documentation, but have not found any answer yet. I have to do this in one search because of sorting.

2

Answers


  1. Chosen as BEST ANSWER

    I have found he answer.

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

    Probably if NRediSearch can handle this or operator within a new query, if not, must be implemented straight through it's client


  2. you can use my library i build over nredisearch. but it works for simple linq queries. its not work on nested objects. I will be glad if you contribute to its development.

    if we talk about your example you have to duplicate your data for each location like this:

    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;}
    }
    

    and you can search this daha with my library.

    RedisworkCore

    PackageManager:

    Install-Package RedisworkCore

    Dotnet CLI:

    dotnet add package RedisworkCore

    and you can create context like 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) { }
    }
    

    then you can use Find, Where, Any, All, SortBy, SortByDescending, Skip, Take similar 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();
      }
      
    }
    

    Notes:

    • You should save your data with redisworkcore otherwise it won’t work.
    • Performance tests were not conducted. It may work better if I can get support as open source.
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search