当我尝试按字段对列表进行分组时,我遇到了内存问题。
输入:这是一个包含类别和一些字段的项目列表:
{ 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'
) ) ) ) ) );
当我尝试从头开始获取输入列表时,一切正常。但是一旦我尝试将它们分组,它就会失败。任何想法为什么或如何解决它?
答案 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,就可以正常工作。