mongo:将面向行的集合转换为面向列的集合

时间:2017-05-11 19:39:15

标签: arrays mongodb

假设我有:

  • 一个大型集合A,包含大量文档,每个文档由同一行的大量字段组成(例如,10 ^ 8行×300字段)
  • 我们希望将其转换为300个集合,每个集合仅包含一个大型值数组(300个数组x 10 ^ 8个值)

这是可能的,因为所有行都具有相同的结构,因此所有结果数组都具有相同的元素。我们可能会看到它是一个大的(10 ^ 8 x 300)矩阵。

我尝试使用$ concatArrays进行聚合,但由于16Mo聚合限制而失败。

我尝试考虑其中一个字段' F'该集合' A'。由于文件数量太大,我决定将流程分为500000步。我将这部分集合转换为一个单独的集合' F'只有一个文档。

outname = 'F';
step = 500000
count = db.A.count()

out = db[outname];
out.drop();
out.insert({F:[]});

op1 = {$arrayElemAt: [ '$x.F', 0 ]};
op2 = {$concatArrays: ['$F', op1]};

start = 0

for(i = 0; start < count; i++)
{
  tmp = 'tmp';
  db[tmp].drop();

  skip = start;

  print(i, skip, start);

  db.Object.aggregate( 
    [ 
      {$project: {'F': 1} }, 
      {$skip:    skip},
      {$limit:   step},
      {$group:   {'_id': '', 'F': {$push: '$F' } } }, 
      {$out:     tmp} 
    ], 
    {allowDiskUse: true} 
  );

  join = {$lookup: {'from': tmp, 'localField': outname + '._id', 'foreignField': tmp + '._id', 'as': 'x'} };
  out.aggregate( [ join, {'$project': {'F': op3} }, {'$out': outname} ], {allowDiskUse: true});

  start += step;
}

当然,基于$ concatArrays的机制是不可扩展的。

你会如何改善这一点? (我的意思是有效,因为那些数组非常庞大)

感谢您的建议

基督教

0 个答案:

没有答案