使用多个嵌套但可能为空的数组在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']}}}
] );