Ravendb map / reduce index不起作用

时间:2017-02-09 13:29:58

标签: c# ravendb

我正在构建索引,但结果并不像预期的那样。

我的目的是找到我在MyClass中的SomeEnumFlag中有多少客户和供应商。 MyClass有Name和SomeEnumFlag,它是一种买卖文件。所以我可以提供以下文件:

{ Name: "Some company name", SomeEnumFlag: "Buy" },
{ Name: "Another company name", SomeEnumFlag: "Buy" },
{ Name: "Another company name", SomeEnumFlag: "Sell" },
{ Name: "Another company name", SomeEnumFlag: "Sell" }

预期结果是:

  • 客户:2;因为有两个不同的公司有“买”;
  • 供应商:1;因为有一个独特的公司有“卖”

因此,公司可以是基于SomeEnumFlag的客户或/和供应商,我应该每次计算一次。

考虑索引:

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

并查询:

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,错误。

但是,如果我写这样的代码:

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,它的权利!

我在内存中以完全相同的方式手动映射/缩减代码,并且它按预期工作。

我的索引有什么问题?我错过了什么?在索引中使用group by有一些限制吗?

提前致谢。

我应该提一下,在Map方法中,我使用复合键进行了分组。所以Name和SomeEnumFlag应该在这两个属性之间有所区别,共有3个枚举({Some company name,Buy},{Another company name,Buy},{Another company name,Sell})。买多少? 2.多少卖?乌鸦指数不起作用。在内存示例中,模拟map / reduce的行为,工作正常。

1 个答案:

答案 0 :(得分:0)

我认为您的索引没有任何问题,我认为您的LINQ查询存在问题。

假设只有3个项目,可以尝试这个查询吗?

var totalSuppliers = reduce.Count(c => c.Kind == eSomeEnumFlag.Buy.ToString())

这会缩短并使逻辑更清晰我认为并且应该让你得到你想要的东西?如果不让我知道,我会更深入地探讨。