运行php mongodb聚合组函数时如何避免内存问题?

时间:2014-04-14 13:44:03

标签: php mongodb mapreduce grouping

当我尝试按字段对列表进行分组时,我遇到了内存问题。

输入:这是一个包含类别和一些字段的项目列表:

{ category: "CATNAME1", field1: "value11", field2: "value21", ... },
{ category: "CATNAME2", field1: "value12", field2: "value22", ... },
{ category: "CATNAME3", field1: "value13", field2: "value23", ... },
{ category: "CATNAME4", field1: "value14", field2: "value24", ... }, ..

输出应该是类别列表,每个类别都包含相应项目的列表:

{ category: "CATNAME1", items: [
    { field1: "value12", field2: "value22", ... },
    { field1: "value14", field2: "value24", ... }, ..
] },
{ category: "CATNAME2", items: [
    { field1: "value12", field2: "value22", ... },
    { field1: "value14", field2: "value24", ... }, ..
] },

//编辑:我们尝试了不同的版本,删除了除了一个以外的所有版本,以提高可读性。

部分解决方案: 这适用于小型列表,但当我有1000个类别,每个类别1000个项目时,内存不足。 :(

$cursor = $collection->aggregate(
    array(
        array(
            '$match' => array(
                .. some filters here ...
            ) ),
        array(
            '$group' => array(
                    '_id' => '$category',
                    'items' => array( '$addToSet' => array(
                        'field1' => '$field1',
                        'field2' => '$field2',
                        'field3' => '$field3',
                        'field4' => '$field4'
                    ) ) ) ) ) );

当我尝试从头开始获取输入列表时,一切正常。但是一旦我尝试将它们分组,它就会失败。任何想法为什么或如何解决它?

2 个答案:

答案 0 :(得分:-1)

如上所述,错误的比赛甚至错误的运动。使用聚合:

db.collection.aggregate([
    { "$group": {
        "_id": "$category",
        "name": { "$first": "$name" },
        "value":  { "$first": "$value" }
    }
])

这是一个非常简单的查询。 .group() 函数几乎应该被视为已弃用。并且 mapReduce 也不适合此类操作,它比聚合使用的本机代码接口运行慢。 mapReduce 方式使用JavaScript解释器,执行速度慢很多倍。


修改

如果你真的只想要集合上的唯一值,那么语句非常简单,就像在SQL中一样:

db.collection.aggregate([
    { "$group": {
        "_id": {
            "category": "$category",
            "name": "$name",
            "value":  "$value"
        }
    }
])

因此,基本上直接对值进行分组而不是“边界”,因此会在组合上产生唯一值。

答案 1 :(得分:-1)

您的架构几乎完全是人们在SQL环境中使用的内容。

尝试将架构更改为

{
    "category": "cat1",
    "values": {
        "item1": "value1",
        "item1": "value2"
    }
 }

只要不同键的数量不超过100或1000,就可以正常工作。