0

I am trying to implement simple sorting in my project where memory of the application is kept in Redis Stack. So far, most features work without too many complications. However, I have found one that might break some logic eventually: When a property is marked as sortable in the main object, OrderBy works without a hitch. However, when I attempt to sort by a property in the embedded object, Redis OM throws the following exception:

Property `Field1` not loaded nor in schema
Failed on FT.SEARCH yes-idx * LIMIT 0 100 SORTBY Field1 ASC

The code is as follows:

var _provider = new RedisConnectionProvider("redis://localhost:6379");
_provider.Connection.DropIndexAndAssociatedRecords(typeof(Yes));
await _provider.Connection.CreateIndexAsync(typeof(Yes));
var coll = _provider.RedisCollection<Yes>();

for (int i = 1; i < 11; i++)
{
    var no = new No() { Field1 = i, Field2 = i * 100};
    var yes = new Yes() { Id = i, NoField = no, Timestamp = DateTime.Now };
    await coll.InsertAsync(yes);
}
var timey = coll.OrderBy(x => x.Timestamp).ToList();
var earlier = timey.FirstOrDefault();
var later = timey.LastOrDefault();
Console.WriteLine($"{earlier.Id} came earlier");
Console.WriteLine($"{later.Id} came later");

var timey2 = coll.OrderBy(x => x.NoField.Field1).ToList(); //throws here
var earlier2 = timey.FirstOrDefault();
var later2 = timey.LastOrDefault();
Console.WriteLine($"{earlier2.Id} came earlier");
Console.WriteLine($"{later2.Id} came later");

[Document(StorageType = StorageType.Json)]
public class Yes
{
    [Indexed, RedisIdField] public int Id { get; set; }
    [Indexed(CascadeDepth = 2)] public No NoField { get; set; }
    [Indexed(Sortable = true)] public DateTime Timestamp { get; set; }
}

public class No
{
    [Indexed(Sortable = true)] public int Field1 { get; set; }
    [Indexed] public int Field2 { get; set; }
}

Any idea why it might not be indexing the sortable property of the embed? There isn't much information on embedded models in the documentation, most cases involve flat models. I may well be doing something wrong, but since Redis Stack is relatively new this could be a genuine bug for all I know.

Johnny Cache
  • 1,033
  • 7
  • 12
  • 1
    Looks like the index is being created correctly, but it's using the wrong field name in the query - should be `NoField_Field1` instead of `Field1` Opened: https://github.com/redis/redis-om-dotnet/issues/321 to address. – slorello Mar 02 '23 at 14:09
  • @slorello Thanks for the info. Any idea when to expect v0.4.2? – Johnny Cache Mar 03 '23 at 06:56
  • Also, know if there's gonna be a LastOrDefault() implementation for RedisCollection in it? If not, I can fork it, my little fix seems to work. Kinda unwieldy to list the collection before I can use the method – Johnny Cache Mar 03 '23 at 07:14
  • Also also, I don't see any support for TimeSpans. Any planned? Could be very useful, especially if it's acceptable to handle it just like DateTime is. Currently TimeSpans seem to be converted to strings when inserted into Redis, but probably incorrectly mapped as well because I get a very similar exception upon trying to read them – Johnny Cache Mar 03 '23 at 07:48
  • I mean sort by them, sorry. They are read correctly – Johnny Cache Mar 03 '23 at 07:54
  • few questions there :) 1. I have a spate of PRs open, when they are merged I'll push out 0.4.2 2. Not going to implement LastOrDefault at this time - you have to paginate over the entire result set to get to it so it's really expensive. I'd suggest reversing the ordering, or just calling LastOrDefault on a materialized List or array - should be equivalent 3. Not atm wrt timespans – slorello Mar 03 '23 at 17:09

0 Answers0