我有一个约500万份文件的表格集。它们如下所示:
fr to weight
6000
和fr
有to
个可能的值。我创建了以下代码,将所有可能的fr
字段中的所有权重加到to
,例如
1 1 sum(all documents with fr=1 to=1)
1 2 sum(all documents with fr=1 to=2)
...
我使用pyMongo
来编写脚本,而cells
是包含所有可能的fr
/ to
字段的数组,calls
是我的集合有我的〜500万份文件。
for _from in cells: #pair up each cell with each other cell
for _to in cells:
s = calls.aggregate([
{
'$match':
{
"fr": _from,
"to": _to
}
},
{
'$group': {'_id': 'null', 'sum': {'$sum':'$weight'}}
}])
if s['result']:
fr_to_sum = s['result'][0]['sum']
_id = entropy.insert({
'to': _to,
'fr': _from,
'sum': fr_to_sum
})
我正在使用一台机器。
另一个数据库会更好吗?例如。一些SQL?
更新
字段fr
和to
包含1-100000
范围内的整数,而weight
是一个小float
。我尝试在fr
和to
之间进行所有可能的组合,并对这些组合的值求和,因为数据库中可能存在具有fr
和to
的重复文档相同(例如fr=1 to=2 weight=0.004
和fr=1 to=2 weight=0.01
,所以在这种情况下,我希望在我的entropy
表格中fr=1 to=2 weight=0.014
。
就像一个样本
>> db.week_calls.count({'fr':10, 'to':102})
>> 4
致电db.week_calls.getIndexes()
后我
{
"v" : 1,
"key" : {
"_id" : 1
},
"ns" : "db.week_calls",
"name" : "_id_"
}
这看起来很奇怪,因为我使用db.calls.ensure_index([("fr",1), ("to",1)])
答案 0 :(得分:1)
您要尝试做的基本形式,没有迭代是这样的:
db.collection.aggregate([
{ "$group": {
"_id": {
"fr" : "$fr",
"to" : "$to",
},
"sum": { "$sum": "$weight" }
}}
])
现在可能会爆炸,因此您可能需要执行一些循环并“range”值,如下所示:
db.collection.aggregate([
{ "$match": {
"fr": { "$gt": 0, "$lte": 10000 },
"to": { "$gt": 0, "$lte": 10000 }
}},
{ "$group": {
"_id": {
"fr" : "$fr",
"to" : "$to",
},
"sum": { "$sum": "$weight" }
}}
])
分段所有这些文档,然后获取下一个段:
db.collection.aggregate([
{ "$match": {
"fr": { "$gt": 10000, "$lte": 20000 },
"to": { "$gt": 10000, "$lte": 20000 }
}},
{ "$group": {
"_id": {
"fr" : "$fr",
"to" : "$to"
},
"sum": { "$sum": "$weight" }
}]
])
哪种解决方案最适合您。
一般来说,让$group
为您完成工作并将其分解为可管理的块,其结果可能对于一次获取而言太大。
在将来的版本中,aggregate将返回一个游标。