Reduce not generating unique enum values when database is not consistent #18439
-
I'm not sure if this should work or not, I would expect it to work since I'm grouping on an enum. But I also understand that the database has no concept of enums during indexing. It's not possible to fix it with Enum.Parse either: group result by new { Day = Enum.Parse<DayOfWeek>(result.Day.ToString()) } into g Because then I get:
Test case and failure
public class EnumReduceTests : RavenTestDriver
{
[Fact]
public void CanReduceEnum()
{
using var store = GetDocumentStore();
store.ExecuteIndex(new FooIndex());
using (var session = store.OpenSession())
{
var untouched = new Foo
{
Day = DayOfWeek.Monday,
Value = "monday-untouched",
};
var saveEnumAsInteger = new Foo
{
Day = DayOfWeek.Monday,
Value = "monday-num",
};
var lower = new Foo
{
Day = DayOfWeek.Monday,
Value = "monday-lower",
};
session.Store(untouched);
session.Store(saveEnumAsInteger);
session.Store(lower);
session.SaveChanges();
// simulate data inconsistencies, like when migrating from SaveEnumAsInteger = true to SaveEnumAsInteger = false
session.Advanced.Defer(new PatchCommandData(saveEnumAsInteger.Id, null, new() { Script = @"this.Day = 1" }));
session.Advanced.Defer(new PatchCommandData(lower.Id, null, new() { Script = @"this.Day = 'monday'" }));
session.SaveChanges();
}
WaitForIndexing(store);
using (var session = store.OpenSession())
{
var days = session
.Query<FooIndex.Result, FooIndex>()
.ToList();
Assert.Single(days);
}
}
public class Foo
{
public string Id { get; set; }
public DayOfWeek Day { get; set; }
public string Value { get; set; }
}
public class FooIndex : AbstractIndexCreationTask<Foo, FooIndex.Result>
{
public FooIndex()
{
Map = foos =>
from f in foos
select new Result
{
Day = f.Day,
Values = new[] { f.Value },
};
Reduce = results =>
from result in results
group result by new { result.Day } into g
select new Result
{
Day = g.Key.Day,
Values = g.SelectMany(x => x.Values).ToArray()
};
}
public class Result
{
public DayOfWeek Day { get; set; }
public string[] Values { get; set; }
}
}
} |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 5 replies
-
Your issue is that on the server side, this is not an enum, but a string. You should either ensure that you use consistent casing or use:
|
Beta Was this translation helpful? Give feedback.
The exception
System.NotSupportedException: Cannot extract field name from: Day = IndexHelper.EnsureEnum(result.Day)
is an internal issue in the RavenDB's index compiler. We'll check that (https://issues.hibernatingrhinos.com/issue/RavenDB-22317/Index-compiler-cannot-extract-Group-By-field-name).You can use
IndexHelper.EnsureEnum()
in the map function instead of the reduce to workaround that. Also I had to modify the extension method to:alternatively you could also try something like: