I've got the following RavenDB index.
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()
});
}
}
When I run it with below query, I get the following results.
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
}
]
The structure of the data is the correct JSON structure that I want but it seems to miss a lot of data. I get results in year 2012 and year 2019 (which are correct). But the other years are empty even though I am 100% sure they container a lot more data than the years 2012 and 2019.
When I change the reduce to the following (removed the second .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()
});
It gives such a weird structure as a result (see blow for a small grab of 2013, because the full JSON is very long).
[
{
... 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
}
]
As you can see 2013 has data, even though in the first JSON result it doesn't show it, but is has a weird structure I didn't expect. That is probably why it doesn't show the 2013 data in the first reduce, I think.
My questions:
I've been stuck on this issue for quite a while now, some help would be appreciated.
RavenDB Client: 4.1.4
RavenDB Server: 4.1.3
The issue is that you are creating fake data in the reduce, but reduce is called multiple times. You have to be able to process it recursively. Try something like this:
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)
})
});
}