Laravel MondoDB - 如何计算和分组记录

时间:2016-02-17 14:17:35

标签: mongodb laravel-5

我在MongoDB中使用Laravel 5.1和jenssegers / laravel-mongodb包。我试图在MongoDB中这样做:

$offers = Offer::select(DB::raw('DATE(created_at) as date'), DB::raw('count(created_at) as cnt'))->groupBy('date')->get();

使用此网址中的示例:https://github.com/jenssegers/laravel-mongodb/issues/361 我试过这个:

// in Offer.php
public function scopePostedJobs($query){
        $q = $query->groupBy('created_at');
        $q->getQuery()->aggregate = [ 'function' => 'count', 'columns' => [ 'created_at' ] ];
        return $q;
    }


// in controller
$postedJobs = Offer::postedJobs()->get();

此示例无法正常工作,因为它按完整时间戳分组,我只需要日期,没有时间。那么我如何按创建组分组,但只使用没有时间的日期?

3 个答案:

答案 0 :(得分:2)

感谢@BrentR和@chridam我找到了这个解决方案:

$postedJobs = Offer::raw()->aggregate(array(
                array(
                    '$group' => array(
                        '_id' => array(
                            'yearMonthDay' => array(
                                '$dayOfYear' => '$created_at'
                            )
                        ),
                        'count' => array( '$sum' => 1 )
                    )
                )   
            ));

由于某种原因$ dateToString对我不起作用所以我使用了@BrentR的建议并且它有效

答案 1 :(得分:1)

您可以使用$ dayOfYear运算符进行mongo聚合来实现此分组。

请参阅https://docs.mongodb.org/v3.0/reference/operator/aggregation/dayOfYear/

答案 2 :(得分:1)

为了获得更好的性能,请使用底层MongoDB驱动程序的聚合框架方法,因为它使用MongoDB服务器上的本机代码,而不是基本上包含mapReduce方法的.groupBy()方法。

考虑以下使用日期运算符的聚合操作 $dateToString 管道中的 $group ,可根据用户指定的格式将日期对象转换为字符串

db.collectionName.aggregate([
    {
        "$group": {
            "_id": {
                "yearMonthDay": { "$dateToString": { format: "%Y-%m-%d", date: "$accesstime" } }
            },
            "count": { "$sum": 1 }
        }
    }
]);

等效的Laravel示例实现:

$postedJobs = DB::collection('collectionName')->raw(function($collection)
{
    return $collection->aggregate(array(
        array(
            "$group" => array(
                "_id" => array(
                    "yearMonthDay" => array(
                        "$dateToString" => array( 
                            format => "%Y-%m-%d", 
                            date => "$created_at" 
                        )
                    )
                ),
                "count" => array( "$sum" => 1 )
            )
        )   
    ));
});