I am building an index, but the results is not as expected.
My intention is find how much clients and suppliers I have based in SomeEnumFlag in MyClass. MyClass has Name and SomeEnumFlag, its a kind of buy or sell document. So I can have documents like:
{ Name: "Some company name", SomeEnumFlag: "Buy" },
{ Name: "Another company name", SomeEnumFlag: "Buy" },
{ Name: "Another company name", SomeEnumFlag: "Sell" },
{ Name: "Another company name", SomeEnumFlag: "Sell" }
The expected result is:
- Clients: 2; 'cause there are two distinct companies with "Buy";
- Suppliers: 1; 'cause there is one distinct company with "Sell"
So, a company can be a client or/and a supplier based on SomeEnumFlag, and I should count each one time.
Consider the index:
public class MyClass_TotalClientsSuppliers_Index : AbstractIndexCreationTask<MyClass, MyClass_TotalClientsSuppliers_Index.Result>
{
public class Result
{
public string Kind { get; set; }
public int Total { get; set; }
}
public MyClass_TotalClientsSuppliers_Index()
{
Map = myClass => from grouped in myClass.GroupBy(c => new { Name = c.Name, Flag = c.SomeEnumFlag.ToString() })
select new
{
Kind = grouped.Key.Flag,
Total = 1
};
Reduce = results => from result in results
group result by result.Kind into g
select new
{
Kind = g.Key,
Total = g.Sum(c => c.Total)
};
}
}
And querying:
var resultTotalClientSupplier = session
.Query<MyClass_TotalClientsSuppliers_Index.Result, MyClass_TotalClientsSuppliers_Index>()
.ToList();
var totalClients = resultTotalClientSupplier.FirstOrDefault(c => c.Kind == eSomeEnumFlag.Buy.ToString())?.Total ?? 0;
var totalSuppliers = resultTotalClientSupplier.FirstOrDefault(c => c.Kind == eSomeEnumFlag.Sell.ToString())?.Total ?? 0;
totalClients = 2.
totalSuppliers = 2, its wrong.
But, if I write a code like this:
var myClasses = session.Query<MyClass>().ToList();
var map = from grouped in myClasses.GroupBy(c => new { Name = c.Name, Flag = c.SomeEnumFlag.ToString() })
select new
{
Kind = grouped.Key.Flag,
Total = 1
};
var reduce = from result in map
group result by result.Kind into g
select new
{
Kind = g.Key,
Total = g.Sum(c => c.Total)
};
var totalClients = reduce.FirstOrDefault(c => c.Kind == eSomeEnumFlag.Buy.ToString())?.Total ?? 0;
var totalSuppliers = reduce.FirstOrDefault(c => c.Kind == eSomeEnumFlag.Sell.ToString())?.Total ?? 0;
totalClients = 2.
totalSuppliers = 1, its right!
I did map/reduce code manually, exactly the same way, in memory, and its works as expected.
What is wrong about my Index? What am I missing? There is some limitation using group by in indexes?
Thanks in advance.
I should mention that in Map method I did a grouping with a compound key. So Name and SomeEnumFlag should work like a distinct between this two properties, with 3 total enumeration ({Some company name, Buy}, {Another company name, Buy}, {Another company name, Sell}). How many Buy? 2. How many Sell? 1. Raven Index is not working. In memory sample, that simulates behavior of map/reduce, works fine.