使用多个嵌套但可能为空的数组在mongodb聚合中展开

使用多个嵌套但可能为空的数组在mongodb聚合中展开,mongodb,aggregation-framework,Mongodb,Aggregation Framework,我收集了很多文件,看起来像这样: { _id: <id> arrayOne: [{name: <string>, listings: [<string>, <string>, ...]}], arrayTwo: [{name: <string>, listings: [<string>, <string>, ...]}] } { _身份证: 数组名:[{name:,列表:[,…]}], arrayT

我收集了很多文件,看起来像这样:

{
  _id: <id>
  arrayOne: [{name: <string>, listings: [<string>, <string>, ...]}],
  arrayTwo: [{name: <string>, listings: [<string>, <string>, ...]}]
}
{
_身份证:
数组名:[{name:,列表:[,…]}],
arrayTwo:[{name:,listings:[,…]}]
}
我需要的是一个平面数组,其中来自arrayOne和arrayTwo的列表中的每个字符串都表示为不重复的字符串,所以我这样做:

aggregate( [
  { $match: { _id: <id>} },
  { $unwind: '$arrayOne' },
  { $unwind: '$arrayOne.listings' },
  { $unwind: '$arrayTwo' },
  { $unwind: '$arrayTwo.listings' },
  { $group : { _id : '$_id', setOne: { $addToSet: '$arrayOne.listings'}, setTwo: {$addToSet: '$arrayTwo.listings'} } },
  { $project: {unique_appearances: {$setUnion: ['$setOne', '$setTwo']}}}
] );
聚合([
{$match:{{u id:}},
{$unwind:'$arrayOne'},
{$unwind:'$arrayOne.listings'},
{$unwind:'$arrayTwo'},
{$unwind:'$arrayTwo.listings'},
{$group:{{{U id:'${U id',setOne:{$addToSet:'$arrayOne.listings'},SETTO2:{$addToSet:'$arrayTwo.listings'}},
{$project:{unique_外观:{$setUnion:['$setOne','$setTwo']}}
] );
在arrayOne或arrayTwo为空的文档上运行之前,这一切都很正常

今天,我通过添加一个伪值(在解卷之前)来解决它,我在最后一行过滤掉它,如下所示:

aggregate( [
  { $match: { _id: <id>} },
  { $project: {
      _id: '$_id',
      arrayOne: { $cond : [{$gt: ['$arrayOne', []]}, '$arrayOne', [{listings: ['cheezeburglars']}]] },
      arrayTwo: { $cond: [{$gt: ['$arrayTwo', []]}, '$arrayTwo', [{listings: ['cheezeburglars']}]] }
    }
  },
  { $unwind: '$arrayOne' },
  { $unwind: '$arrayOne.listings' },
  { $unwind: '$arrayTwo' },
  { $unwind: '$arrayTwo.listings' },
  { $group : { _id : '$_id', setOne: { $addToSet: '$arrayOne.listings'}, setTwo: {$addToSet: '$arrayTwo.listings'} } },
  { $project: {
    unique_appearances:  {
      $setDifference: [{$setUnion: ['$setOne: ', '$setTwo']}, ['cheezeburglars']]
    }
  }}
] );
聚合([
{$match:{{u id:}},
{$项目:{
_id:“$\u id”,
arrayOne:{$cond:[{$gt:['$arrayOne',[]},$arrayOne',[{列表:['Cheezeburlars']}]},
arrayTwo:{$cond:[{$gt:['$arrayTwo',[]},$arrayTwo',[{列表:['Cheezeburlars']}]}
}
},
{$unwind:'$arrayOne'},
{$unwind:'$arrayOne.listings'},
{$unwind:'$arrayTwo'},
{$unwind:'$arrayTwo.listings'},
{$group:{{{U id:'${U id',setOne:{$addToSet:'$arrayOne.listings'},SETTO2:{$addToSet:'$arrayTwo.listings'}},
{$项目:{
独特的外观:{
$setDifference:[{$setUnion:['$setOne:','$setTwo']},['Cheezeburgrars']]
}
}}
] );

这是可行的,但我觉得我的解决方案有点粗糙。有更好的方法解决这个问题吗?

您可以在MongoDB 3.2+中通过在相关阶段中包含
preserveNullandEmptyArray:true
选项来实现这一点:

聚合([
{$match:{{u id:}},
{$unwind:{path:'$arrayOne',preserveNullandmptyarray:true},
{$unwind:'$arrayOne.listings'},
{$unwind:{path:'$arrayTwo',preserveNullandmptyarray:true},
{$unwind:'$arrayTwo.listings'},
{$group:{{{U id:'${U id',setOne:{$addToSet:'$arrayOne.listings'},SETTO2:{$addToSet:'$arrayTwo.listings'}},
{$project:{unique_外观:{$setUnion:['$setOne','$setTwo']}}
] );

设置该选项将导致
$unwind
在输出中仍然包含文档,即使该字段为空(或null或缺失)。

这是一个不错的选择!谢谢
aggregate( [
  { $match: { _id: <id>} },
  { $unwind: { path: '$arrayOne', preserveNullAndEmptyArrays: true } },
  { $unwind: '$arrayOne.listings' },
  { $unwind: { path: '$arrayTwo', preserveNullAndEmptyArrays: true } },
  { $unwind: '$arrayTwo.listings' },
  { $group : { _id : '$_id', setOne: { $addToSet: '$arrayOne.listings'}, setTwo: {$addToSet: '$arrayTwo.listings'} } },
  { $project: {unique_appearances: {$setUnion: ['$setOne', '$setTwo']}}}
] );