【发布时间】:2017-12-26 07:36:56
【问题描述】:
我有 2 个集合,比如 A 和 B。
示例 A:
[
{"Account": "99", "Cat_1": "Losses", "Cat_2": "Marketing"},
{"Account": "89", "Cat_1": "Losses", "Cat_2": "Consultancy"},
{"Account": "79", "Cat_1": "Losses", "Cat_2": "Marketing"},
{"Account": "69", "Cat_1": "Losses", "Cat_2": "Consultancy"},
{"Account": "59", "Cat_1": "Profits", "Cat_2": "Marketing"},
{"Account": "49", "Cat_1": "Profits", "Cat_2": "Consultancy"},
{"Account": "29", "Cat_1": "Profits", "Cat_2": "Marketing"},
{"Account": "00", "Cat_1": "Profits", "Cat_2": "Consultancy"}
...
]
示例 B:
[
{"Name": "Example A", "Year": 2014, "Account": "99", "Amount": -5000},
{"Name": "Example A", "Year": 2015, "Account": "99", "Amount": -5000},
{"Name": "Example A", "Year": 2014, "Account": "89", "Amount": -2000},
{"Name": "Example A", "Year": 2015, "Account": "79", "Amount": -3000},
{"Name": "Example A", "Year": 2014, "Account": "69", "Amount": 0},
{"Name": "Example A", "Year": 2015, "Account": "59", "Amount": 100},
{"Name": "Example A", "Year": 2016, "Account": "49", "Amount": 5000},
{"Name": "Example A", "Year": 2014, "Account": "29", "Amount": 4000},
{"Name": "Example A", "Year": 2015, "Account": "00", "Amount": 900},
{"Name": "Example B", "Year": 2013, "Account": "99", "Amount": -500},
{"Name": "Example B", "Year": 2011, "Account": "89", "Amount": -10000},
...
]
例如,现在我想获取所有“Cat_1”帐户及其类型,最终得到以下结果:
[
{"cat": "Losses", "Accounts": ["99", "89", "79", "69"]},
{"cat": "Profits", "Accounts": ["59", "49", "29", "00"]}
]
或者,我会为某个类别获取 Cat_n 并获得同样的结果。
接下来我展开 Accounts 并对集合 B 执行查找。这是出现问题的地方,并且超出了最大文档大小。我应该提一下,我一次只对 1 个用户感兴趣,所以我的查找现在看起来像这样:
...
{
"$lookup": {
"from": "collection_B",
"localField": "Account",
"foreignField": "Account",
"as": "results"
}
},
{
"$addFields": {
"results": {
"$filter": {
"input": "$results",
"as": "comp",
"cond": {
"$eq": [
"$$results.Name", "Example A"
]
}
}
}
}
},
...
查找后,我使用 $addFields 覆盖原始结果字段,因为我不想要其中的大多数,因为我只对特定的用户感兴趣。
第二个集合中有大约 1000 万个文档,每个用户大约 300k。因此,在此查找之后,结果中永远不会超过 300k。当请求cat_1 类别时,结果将是两个数组“Losses”和“Profits”,它们都包含大约 800 个帐户。
我使用$project 减小了文档大小,只包含我真正想要的字段。此外,我还尽可能早地使用$match 以从聚合中消除不需要的文档。
但这一切都无济于事,文档不断增长,超过了 16MB BSON 的限制。只有当$limit 使用相当低的±300 值时,才会返回结果并且缺少信息。
我最终感兴趣的是为给定的用户和Cat_n生成一个包含类似内容的文档
{
"Name": "Example A",
"Losses": [
{"Year": 2014, "Amount": ...},
{"Year": 2015, "Amount": ...},
{"Year": 2016, "Amount": ...}
],
"Profits": [
{"Year": 2014, "Amount": ...},
{"Year": 2015, "Amount": ...},
{"Year": 2016, "Amount": ...}
],
}
我一直在考虑只创建两个单独的聚合,一个用于获取类别,另一个用于聚合集合 B 的结果。但是我必须检查每个文档以找出它属于哪个类别,这并不看起来效率不高。 或者,我可以创建第三个集合,在其中合并两个集合中的文档并在那里进行聚合,但如果可能的话,我宁愿避免这样做,因为它会在以后维护或查看这些数据时增加额外的复杂性。
【问题讨论】:
-
您看过这个“2.6 版更改:db.collection.aggregate() 方法返回一个游标,可以返回任何大小的结果集。以前的版本在单个文档中返回所有结果,并且结果集的大小限制为 16 MB"docs.mongodb.com/manual/reference/method/…
-
@DanieleTassone,有趣的功能!虽然它现在没有解决我的问题,但我觉得我可能会在以后的某个地方使用它