如何正确组织RavenDB Map / Reduce结果?

时间:2019-03-02 15:58:33

标签: mapreduce ravendb ravendb4

我有以下RavenDB索引。

public class MyDomain_WeeklyPerYear : AbstractIndexCreationTask<Entities.MyDomain, MyDomain_YearlyTotals.Result>
{
    public class Result
    {
        public int ProcessWeek { get; set; }
        public int ProcessYear { get; set; }
        public int Total { get; set; }
        public object Weeks { get; set; }
        public string Workspace { get; set; }
    }

    public MyDomain_WeeklyPerYear()
    {
        Map = data => data
            .Select(x => new
            {
                x.ProcessWeek,
                x.ProcessYear,
                x.Workspace,
                Total = 1,
                Weeks = (List<object>) null
            });

        Reduce = results => results
            .GroupBy(x => x.ProcessYear)
            .OrderBy(x => x.Key)
            .Select(x => new
            {
                ProcessWeek = 0,
                ProcessYear = x.Key,
                Workspace = (string) null,
                Total = 0,
                Weeks = x
                    .GroupBy(y => y.ProcessWeek)
                    .OrderBy(y => y.Key)
                    .Select(y => new
                    {
                        Week = y.Key,
                        Total = y.Sum(z => z.Total)
                    })
                    .ToList()
            });
    }
}

使用以下查询运行它时,得到以下结果。

var data = await Session
    .Query<MyDomain_WeeklyPerYear.Result, MyDomain_WeeklyPerYear>()
    .ToListAsync();
[
    {
        "processWeek": 0,
        "processYear": 2012,
        "total": 0,
        "weeks": [
            {
                "Week": 1,
                "Total": 8
            },
            {
                "Week": 49,
                "Total": 4
            },
            {
                "Week": 50,
                "Total": 6
            },
            {
                "Week": 51,
                "Total": 11
            },
            {
                "Week": 52,
                "Total": 4
            }
        ],
        "workspace": null
    },
    {
        "processWeek": 0,
        "processYear": 2013,
        "total": 0,
        "weeks": [
            {
                "Week": 0,
                "Total": 0
            }
        ],
        "workspace": null
    },
    {
        "processWeek": 0,
        "processYear": 2014,
        "total": 0,
        "weeks": [
            {
                "Week": 0,
                "Total": 0
            }
        ],
        "workspace": null
    },
    {
        "processWeek": 0,
        "processYear": 2015,
        "total": 0,
        "weeks": [
            {
                "Week": 0,
                "Total": 0
            }
        ],
        "workspace": null
    },
    {
        "processWeek": 0,
        "processYear": 2016,
        "total": 0,
        "weeks": [
            {
                "Week": 0,
                "Total": 0
            }
        ],
        "workspace": null
    },
    {
        "processWeek": 0,
        "processYear": 2017,
        "total": 0,
        "weeks": [
            {
                "Week": 0,
                "Total": 0
            }
        ],
        "workspace": null
    },
    {
        "processWeek": 0,
        "processYear": 2018,
        "total": 0,
        "weeks": [
            {
                "Week": 0,
                "Total": 0
            }
        ],
        "workspace": null
    },
    {
        "processWeek": 0,
        "processYear": 2019,
        "total": 0,
        "weeks": [
            {
                "Week": 2,
                "Total": 14
            },
            {
                "Week": 3,
                "Total": 30
            },
            {
                "Week": 4,
                "Total": 42
            },
            {
                "Week": 5,
                "Total": 52
            },
            {
                "Week": 6,
                "Total": 51
            },
            {
                "Week": 7,
                "Total": 39
            },
            {
                "Week": 8,
                "Total": 53
            },
            {
                "Week": 9,
                "Total": 47
            },
            {
                "Week": 10,
                "Total": 52
            }
        ],
        "workspace": null
    }
]

数据的结构是我想要的正确JSON结构,但似乎丢失了许多数据。我在2012年和2019年得到了结果(正确)。但是其他年份是空的,即使我100%确定它们所存储的数据比2012年和2019年要多得多。

当我将减少值更改为以下内容(删除了第二个.Select()):

Reduce = results => results
    .GroupBy(x => x.ProcessYear)
    .OrderBy(x => x.Key)
    .Select(x => new
    {
        ProcessWeek = 0,
        ProcessYear = x.Key,
        Workspace = (string) null,
        Total = 0,
        Weeks = x
            .GroupBy(y => y.ProcessWeek)
            .OrderBy(y => y.Key)
            .ToList()
    });

结果是这样的结构很奇怪(请参阅一小段关于2013的打击,因为完整的JSON很长)。

[
    {
        ... other years
    },
    {
        "processWeek": 0,
        "processYear": 2013,
        "total": 0,
        "weeks": [
            {
                "ProcessWeek": 0,
                "ProcessYear": 2013,
                "Workspace": null,
                "Total": 0,
                "Weeks": [
                    [
                        {
                            "ProcessWeek": 7,
                            "ProcessYear": 2013,
                            "Workspace": "my-workspace",
                            "Total": 1,
                            "Weeks": null
                        },
                        {
                            "ProcessWeek": 7,
                            "ProcessYear": 2013,
                            "Workspace": "my-workspace",
                            "Total": 1,
                            "Weeks": null
                        },
                        {
                            "ProcessWeek": 7,
                            "ProcessYear": 2013,
                            "Workspace": "my-workspace",
                            "Total": 1,
                            "Weeks": null
                        },
                        {
                            "ProcessWeek": 7,
                            "ProcessYear": 2013,
                            "Workspace": "my-workspace",
                            "Total": 1,
                            "Weeks": null
                        },
                        {
                            "ProcessWeek": 7,
                            "ProcessYear": 2013,
                            "Workspace": "my-workspace",
                            "Total": 1,
                            "Weeks": null
                        },
                        {
                            "ProcessWeek": 7,
                            "ProcessYear": 2013,
                            "Workspace": "my-workspace",
                            "Total": 1,
                            "Weeks": null
                        },
                        {
                            "ProcessWeek": 7,
                            "ProcessYear": 2013,
                            "Workspace": "my-workspace",
                            "Total": 1,
                            "Weeks": null
                        },
                        {
                            "ProcessWeek": 7,
                            "ProcessYear": 2013,
                            "Workspace": "my-workspace",
                            "Total": 1,
                            "Weeks": null
                        },
                        {
                            "ProcessWeek": 7,
                            "ProcessYear": 2013,
                            "Workspace": "my-workspace",
                            "Total": 1,
                            "Weeks": null
                        },
                        {
                            "ProcessWeek": 7,
                            "ProcessYear": 2013,
                            "Workspace": "my-workspace",
                            "Total": 1,
                            "Weeks": null
                        },
                        {
                            "ProcessWeek": 7,
                            "ProcessYear": 2013,
                            "Workspace": "my-workspace",
                            "Total": 1,
                            "Weeks": null
                        },
                        {
                            "ProcessWeek": 7,
                            "ProcessYear": 2013,
                            "Workspace": "my-workspace",
                            "Total": 1,
                            "Weeks": null
                        },
                        {
                            "ProcessWeek": 7,
                            "ProcessYear": 2013,
                            "Workspace": "my-workspace",
                            "Total": 1,
                            "Weeks": null
                        },
                        {
                            "ProcessWeek": 7,
                            "ProcessYear": 2013,
                            "Workspace": "my-workspace",
                            "Total": 1,
                            "Weeks": null
                        },
                        {
                            "ProcessWeek": 7,
                            "ProcessYear": 2013,
                            "Workspace": "my-workspace",
                            "Total": 1,
                            "Weeks": null
                        }
                    ],
                    [
                        {
                            "ProcessWeek": 12,
                            "ProcessYear": 2013,
                            "Workspace": "my-workspace",
                            "Total": 1,
                            "Weeks": null
                        },
                        {
                            "ProcessWeek": 12,
                            "ProcessYear": 2013,
                            "Workspace": "my-workspace",
                            "Total": 1,
                            "Weeks": null
                        },
                        {
                            "ProcessWeek": 12,
                            "ProcessYear": 2013,
                            "Workspace": "my-workspace",
                            "Total": 1,
                            "Weeks": null
                        },
                    ]
                ]
            }
        ]
    },
    {
        ... other years
    }
]

您可以看到2013年有数据,即使在第一个JSON结果中它没有显示它,但它具有我没想到的奇怪结构。我认为,这可能就是为什么它没有在第一次减少中显示2013年数据的原因。

我的问题:

  1. 为什么首先给我一个带有一些正确数据(2012年和2019年)但又缺少其他年份的正确结构的信息?
  2. 为什么它给我怪异的JSON结构,在第二个简化中却显示了其他年份的数据?
  3. 如何从第一个JSON示例获取结构中的所有数据?

我已经在这个问题上停留了很长时间,希望能得到一些帮助。

RavenDB Client: 4.1.4
RavenDB Server: 4.1.3

1 个答案:

答案 0 :(得分:2)

问题是您在reduce中创建虚假数据,但是reduce被多次调用。您必须能够递归处理它。 尝试这样的事情:

public MyDomain_WeeklyPerYear()
{
    Map = data => data
        .Select(x => new
        {
            x.ProcessYear,
            Weeks = new [] {
                new {Week = x.ProcessWeek, Total = 1}
            }
        });

    Reduce = results => results
        .GroupBy(x => x.ProcessYear)
        .Select(x => new
        {
            ProcessYear = x.Key,
            Weeks = x.SelectMany(y=>y.Weeks)
                .GroupBy(y => y.ProcessWeek)
                .Select(y => new
                {
                    Week = y.Key,
                    Total = y.Sum(z => z.Total)
                })
        });
}