如何将MongoDB聚合查询转换为jenssegers中的Laravel MongoDB?

6

我有一个名为changes的MongoDB集合,其中包含以下数据:

{
    "date" : ISODate("2014-06-09T00:00:00.000Z"),
    "field" : "ip",
    "from" : "157.11.209.123",
    "to" : "107.21.109.254"
}
{
    "date" : ISODate("2014-05-15T00:00:00.000Z"),
    "field" : "ip",
    "from" : "107.21.109.254",
    "to" : "157.11.209.123"
}
{
    "date" : ISODate("2014-06-09T00:00:00.000Z"),
    "field" : "registration",
    "from" : "Old service",
    "to" : "Some new service"
}

接下来,我想制作一个典型的SQL查询,通过字段对其进行计数并分组。因此,我已经在MongoDB中创建了查询。

db.changes.group({
    "key": {
        "field": true
    },
    "initial": {
        "count": 0,
    },
    "reduce": function(obj, prev) {
            prev.count++;
    },
});

这段代码运行良好,但如何将其转换为与Laravel 4兼容的代码?我正在使用jenssegers/laravel-mongodb与MongoDB服务器通信。

此外,我的查询中有更多条件,我已经将它们移除以使问题更清晰,因此我正在寻找将该查询精确转换为Laravel代码的解决方案,而不是其他可能的解决方案:)。

2个回答

11

你最好使用聚合框架方法,并深入到底层驱动程序提供的原始MongoDB集合对象中进行操作。这比尝试翻译语法要好得多:

// Returns the original Mongo Result
$result = DB::collection('changes')->raw(function($collection)
{
    return $collection->aggregate(array(
        array(
            '$group' => array(
                '_id' => '$field',
                'count' => array(
                    '$sum' => 1
                )
            )
        )   
    ));
});

结果与像 .group() 这样的方法的结果略有不同,但这使用了 MongoDB 服务器上的本机代码,而不像 .group() 方法那样依赖于 JavaScript 解释,实际上是 mapReduce 的包装器。
最终结果要快得多,并且通常比您从本机框架接口中获得的效率更高。
因此,请使用原生 MongoDB 方式以获得最佳性能。

好的,这很棒,但可能有一个缺点。我需要在一定时间内计算所有内容(上周和上个月)。我不想运行两个查询,而可以只运行一个。我已经附上了我的原始查询。在您的示例中,如何运行自定义reduce函数? - Mateusz Nowak
2
@estshy,你改变问题的方式确实不是一个好主意。对于那些看到提供的答案与您所问的问题不符的人来说,这是非常误导的。如果您发布另一个问题,我和其他人都会很乐意回答。在这里,通常是一个问题一个答案的情况。我可以回答您的附加问题,但它应该是完全不同的另一个问题。请单独发布它。 - Neil Lunn

0

即使这是一个问题,在存储库维基中有一个有用的条目:复杂聚合调用

希望它能帮助像我一样的其他人 ;)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接