I am trying to create a MapReduce program that counts the number of orders by clients within the last year, month, and week.
var mapOrders = function() {
var v_order = {
order_date : this.dt_order
...
};
emit(this.clientid, v_order);
};
var reduceOrders = function(p_clientid, p_orders) {
// Initialize counters for output format
var r_result = { orders_count : {
total: {
1year: 0,
1month: 0,
7day: 0
}
...
}}
for (var c_order = 0; c_order < p_orders.length; c_order++) {
// Increment counters
}
return (r_result);
};
db.orders.mapReduce(
mapOrders,
reduceOrders,
{
out: { merge: "tmp_orders_indicators" }
}
)
The resulting collection contains two types of records:
{
"_id": 80320,
"value": {
"order_date": ISODate("2015-10-30T11:09:51.000Z")
...
}
}
{
"_id": 80306,
"value": {
"orders_count": {
"total": {
"count_1year": 18,
"count_1month": 6,
"count_7day": 1
}
...
}
}
Clients with only one order do not pass through the reduce function, as per MongoDB documentation's explanation:
MongoDB will not call the reduce function for a key that has only a single value.
To ensure all records go through the reduce function and have a consistent output structure like this, is there a way to achieve that?
{
"_id": 80306,
"value": {
"orders_count": {
"total": {
"count_1year": 18,
"count_1month": 6,
"count_7day": 1
}
...
}
}