Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/411.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 我可以让Mongo map减少对象的多个值吗?_Javascript_Mongodb_Mapreduce - Fatal编程技术网

Javascript 我可以让Mongo map减少对象的多个值吗?

Javascript 我可以让Mongo map减少对象的多个值吗?,javascript,mongodb,mapreduce,Javascript,Mongodb,Mapreduce,我有一个集合,我正试图通过id和日期映射,以生成一个产品在店销售与在线销售的图表。每个事务都会创建一个新对象,因此我希望将它们减少到给定日期的总计数。对象的外观如下所示: object { "ProductID": 1 "Purchase Method": In Store "Date": 2018-01-16 "Count": 5 } { "_id" : { "ProductId" : 1, "Date"

我有一个集合,我正试图通过id和日期映射,以生成一个产品在店销售与在线销售的图表。每个事务都会创建一个新对象,因此我希望将它们减少到给定日期的总计数。对象的外观如下所示:

object
{
      "ProductID": 1
      "Purchase Method": In Store
      "Date": 2018-01-16
      "Count": 5
}
{
    "_id" : {
        "ProductId" : 1,
        "Date" : "2018-01-16",
        "Method" : "Online"
    },
    "value" : {
        "Name" : "Online",
        "Count" : 3
    }
}
我试图实现的输出是将店内和在线购买合并到一个对象中,其中一个键是id和日期,然后值是每个方法的计数,如下所示:

ProductID: 1
Date: 2018-01-16
[
    {Name: "In store", Count: 3}
    {Name: "Online", Count: 2}
]
我当前的方法是按Id、日期和购买方法映射对象,这样reduce将使用该方法获得该Id在该日期的总计数,但这导致Id和日期有两个条目,一个用于店内,一个用于在线。这是我的功能的当前状态:

var mapDailySales = function() {
var sale = this;

/*Converts timestamp to just date */
var pad = function pad(n, width, z) {
z = z || '0';
n = n + '';
return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
};

var d = sale.Date;
var date = d.getFullYear() + "-" + pad(d.getMonth() + 1, 2, 0) + "-" + pad(d.getDate(), 2, 0);

emit({ProductId: sale.ProductID, Date:date, Method: sale.PurchaseMethod},
{Name: sale.PurchaseMethod, Count: 1})
};


var reduceDailySales = function(key, value) {
var res = {Name: 0, Count: 0};

value.forEach(function(value){
res.Name = value.Name;
res.Count += value.Count;
});

return res; 
};
当前输出如下所示:

object
{
      "ProductID": 1
      "Purchase Method": In Store
      "Date": 2018-01-16
      "Count": 5
}
{
    "_id" : {
        "ProductId" : 1,
        "Date" : "2018-01-16",
        "Method" : "Online"
    },
    "value" : {
        "Name" : "Online",
        "Count" : 3
    }
}

有没有一种方法可以在不重新对当前输出进行映射缩减的情况下实现我想要的输出?

您可以使用聚合管道而不是mapReduce来获得结果,
$group
按ProductID和日期,使用
$project
可以将计数映射到数组

添加了
$out
以将结果写入新集合,删除它将返回光标

db.prod.aggregate([
    {$group : {
        _id : {ProductID : "$ProductID", Date : "$Date"},
        onlineCount : {$sum : {$cond : [{$eq : ["$PurchaseMethod", "Online"]}, "$Count" , 0]}},
        storeCount : {$sum : {$cond : [{$eq : ["$PurchaseMethod", "In Store"]}, "$Count" , 0]}}
        }
    },
    {$project : {
        _id : 0,
        ProductID : "$_id.ProductID",
        Date : "$_id.Date",
        counts : [{Name: "In Store", Count: "$storeCount"},{Name : "Online", Count: "$onlineCount"}]
    }},
    {$out : "count_stats"}
]).pretty()
收藏

> db.prod.find()
{ "_id" : ObjectId("5a98ce4a62f54862fc7cd1f5"), "ProductID" : 1, "PurchaseMethod" : "In Store", "Date" : "2018-01-16", "Count" : 5 }
{ "_id" : ObjectId("5a98ce4a62f54862fc7cd1f6"), "ProductID" : 1, "PurchaseMethod" : "Online", "Date" : "2018-01-16", "Count" : 2 }
> 
结果

> db.count_stats.find()
{ "_id" : ObjectId("5a98d3366a5f43b12a39b4ac"), "ProductID" : 1, "Date" : "2018-01-16", "counts" : [ { "Name" : "In Store", "Count" : 5 }, { "Name" : "Online", "Count" : 2 } ] }
> 
如果要使用
mapReduce
,可以使用finalize进一步减少或转换结果

db.prod.mapReduce(
    <map>,
    <reduce>,
    {
        out: <collection>,
        finalize: <function>
    }
)
db.prod.mapReduce(
,
,
{
输出:,
最后确定:
}
)