Mongo mapreduce - 在映射阶段使用$ dateToString

时间:2016-09-01 11:18:45

标签: php mongodb mapreduce aggregation-framework doctrine-odm

我有简单的元素集合,具有以下结构:

{
   _id: MongoId
   pvs: int
   day: IsoDate()
   uid: int
}

我想使用MapReduce来计算给定用户的综合浏览量,按特定日期范围(日/周/月,日期format兼容)进行分组。

我遇到的问题是如何在发布之前使用IsoDate在地图功能中重新格式化$dateToString,因此它会激活我想要的格式,例如%Y-%m-%d或{{1} }或%Y-%m。 当我调用它时,我没有重新格式化日期,而是使用%Y-%m-%Uformat字段对象。

示例:

date

将返回

function(){
    emit(
        {'$dateToString': {'format': "%Y-%m-%d", 'date': this.day}}, 
        this.pvs
    )}

我希望将其返回:

{
    "pvs" : 5
    "$dateToString" : {
        "format" : "%Y-%m-%d",
        "date" : ISODate("2016-07-13T08:27:29.000Z")
    }
}

1 个答案:

答案 0 :(得分:1)

如果使用mapReduce,那么你必须创建自己的自定义函数来格式化日期并在map函数中调用它:

dateToString = function(date){
    return date.getFullYear() + '-' (date.getMonth() + 1) + '-' + date.getDate();
}

map = function() {
    emit(dateToString(this.day), this.pvs);
}

更好的聚合框架在其C ++代码中“运行”MongoDB,因此更有效的mapReduce在捆绑的JS控制台中的V8 / spidermonkey(取决于您的版本)环境中运行:

db.collectionName.aggregate([
    { "$match": { "uid": userId } },
    { 
        "$project": {
            "formattedDate": { 
                "$dateToString": { "format": "%Y-%m-%d", "date": "$day" } 
            },
            "pvs": 1
        }
    },
    {
         "$group": {
             "_id": "$formattedDate",
             "pvs": { "$sum": "$pvs" }
         }
    }
])

在doctrine mongo odm中,您可以使用command函数运行管道:

$connection = $this->get('doctrine_mongodb')->getConnection();
$mongo = $connection->getMongo();
if (!$mongo) {
    $connection->connect();
    $mongo = $connection->getMongo();
}
$db = $mongo->selectDB('test_database');
$aggregate_results = $db ->command(array( 
    "aggregate" => "collectionName",
    "pipeline" => array( 
        array("$match" => array("uid"=>  userId )),
        array( 
            "$project" => array(
                "formattedDate" => array( 
                    "$dateToString" => array("format" => "%Y-%m-%d", "date"=>  "$day") 
                ),
                "pvs" =>  1
            )
        ),
        array(
             "$group" => array(
                 "_id" => "$formattedDate",
                 "pvs" => array("$sum" => "$pvs")
             )
        )
    )
));