$reduce and $setUnion for nested arrays in MongoDB

2020-02-07 06:39发布

问题:

I am looking to merge nested arrays using $reduce and $setUnion in MongoDB. Following is the sample input -

levels: [
 [[80,100,120]],[[100,150]],[[200,80,100]],[[80,100]]
]

The output what I am intended to get (i.e. merge nested arrays with unique values) - levels: [80,100,120,150,100]

I am able to get the above output using two ways -

1) Using two $project stages in pipeline -

aggregate([
$project: { levels : { $reduce: {
input: "$levels", initialValue: [], in:{$setUnion:["$$value","$$this"]}}}},
$project: { levels : { $reduce: {
input: "$levels", initialValue: [], in:{$setUnion:["$$value","$$this"]}}}}
])

2) First $unwind and then $project

aggregate([
$unwind: { '$levels'}},
$project: { levels : { $reduce: {
input: "$levels", initialValue: [], in:{$setUnion:["$$value","$$this"]}}}}
])

Can there be any improved way of first option where I don't need to use the same $project twice? I am trying to avoid unwind.

回答1:

You can use below aggregation with single $project stage

db.collection.aggregate([
  { "$project": {
    "levels": {
      "$reduce": {
        "input": {
          "$reduce": {
            "input": "$levels",
            "initialValue": [],
            "in": { "$setUnion": ["$$this", "$$value"] }
          }
        },
        "initialValue": [],
        "in": { "$setUnion": ["$$this", "$$value"] }
      }
    }
  }}
])