Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays mongo:将面向行的集合转换为面向列的集合_Arrays_Mongodb - Fatal编程技术网

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

Arrays mongo:将面向行的集合转换为面向列的集合,arrays,mongodb,Arrays,Mongodb,假设我有: 一个大型集合a,包含大量文档,每个文档由同一行的大量字段组成(例如10^8行x 300个字段) 我们希望将其转换为300个集合,每个集合只包含一个大的值数组(300个数组x 10^8个值) 这是可能的,因为所有行都具有相同的结构,因此所有生成的数组都具有相同的元素。我们可以将其视为一个大的(10^8 x 300)矩阵 我尝试过使用$concatarray进行聚合,但由于聚合的16Mo限制,它失败了 这是我尝试考虑集合“A”中的一个字段“F”时的结果。由于文档的数量太多,我决定将流

假设我有:

  • 一个大型集合a,包含大量文档,每个文档由同一行的大量字段组成(例如10^8行x 300个字段)
  • 我们希望将其转换为300个集合,每个集合只包含一个大的值数组(300个数组x 10^8个值)
这是可能的,因为所有行都具有相同的结构,因此所有生成的数组都具有相同的元素。我们可以将其视为一个大的(10^8 x 300)矩阵

我尝试过使用$concatarray进行聚合,但由于聚合的16Mo限制,它失败了

这是我尝试考虑集合“A”中的一个字段“F”时的结果。由于文档的数量太多,我决定将流程分为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;
}
outname='F';
步长=500000
count=db.A.count()
out=db[outname];
out.drop();
out.插入({F:[]});
op1={$arrayElemAt:['$x.F',0]};
op2={$concatarray:['$F',op1]};
开始=0
对于(i=0;开始<计数;i++)
{
tmp=‘tmp’;
db[tmp].drop();
跳过=开始;
打印(i、跳过、开始);
db.Object.aggregate(
[ 
{$project:{'F':1},
{$skip:skip},
{$limit:step},
{$group:{''u id':''F':{$push:'$F'}},
{$out:tmp}
], 
{allowDiskUse:true}
);
join={$lookup:{'from':tmp,'localField':outname+'.\u id','foreignField':tmp+'.\u id','as':'x'};
聚合([join,{'project':{'F':op3},{'out':outname}],{allowDiskUse:true});
开始+=步进;
}
当然,基于$concatarray的机制是不可伸缩的

你将如何改进这一点?(我的意思是高效,因为这些阵列非常庞大)

谢谢你的建议


Christian

不清楚,你为什么还要继续使用mongodb来实现这一点。300个集合,每个集合包含一个数组?也可以将数组存储在普通文件中。当然,您的评论是合法的。我仍然希望利用Mongo的特性(查询、聚合等)。我只是注意到当前的结构(面向行)是不有效的,因为每个搜索都必须遍历整个集合。。。除非我设置了索引(那么时间是相当不错的)。但是,我不想创建300个索引(!!),它们乘以基本大小的6。!!!。也许我会从原始数据中重新创建我的基础(这在我的用例中是可能的)。。。我一直在搜索…只是想澄清一下,您计划如何在这300个集合中存储数据?每值文档数?还是一个/几个文档中的所有值?如果是后者,那么查询/聚合可能很难使用。为了使查询在每值文档场景中高效,您需要300个索引……确切地说,我的问题是关于最佳模型的。最初,数据是作为一个大型CSV文件提供的(10^8行,共300项)。我的第一次尝试是创建一个大集合(10^8个文档,每个文档有300个字段)。这很好,但只适用于索引(当然)。我想知道另一个组织是否会更好。(例如,300个集合,每个集合有一个数组10^8个值)。还请注意,此数据集不会更改。固定(平面)结构记录的不可变数据集?这是mongodb的终极反用例。您是否考虑过关系型/列型数据库?例如,Postgresql或vertica?