Как правильно организовать RavenDB Map/Reduce результаты?

У меня есть следующий индекс 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

0 ответов

Проблема заключается в том, что вы создаете ложные данные в методе 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)
                })
        });
}
Другие вопросы по тегам