How to merge output from unwind mongodb?

For example, I have data in a collection like this:

db.inventory2.insertMany([
  { "_id" : 1, "item" : "ABC", price: NumberDecimal("80"), "sizes": [ "S", "M", "L"] },
  { "_id" : 2, "item" : "EFG", price: NumberDecimal("120"), "sizes" : [ ] },
  { "_id" : 3, "item" : "IJK", price: NumberDecimal("160"), "sizes": ["M"] },
])

And, when adding $unwind, I want to select the item which has sizes is not null.

The result after I add $unwind:

db.inventory2.aggregate( [ { $unwind: { path: "$sizes" } } ] )
{ "_id" : 1, "item" : "ABC", "price" : NumberDecimal("80"), "sizes" : "S" }
{ "_id" : 1, "item" : "ABC", "price" : NumberDecimal("80"), "sizes" : "M" }
{ "_id" : 1, "item" : "ABC", "price" : NumberDecimal("80"), "sizes" : "L" }
{ "_id" : 3, "item" : "IJK", "price" : NumberDecimal("160"), "sizes" : "M" }

My question is, when I add $unwind, how to not separate the result item "ABC". My expectation result is like this:

{ "_id" : 1, "item" : "ABC", "price" : NumberDecimal("80"), "sizes" : ["S", "M", "L"] }
{ "_id" : 3, "item" : "IJK", "price" : NumberDecimal("160"), "sizes" : ["M"] }

Thanks before for your help.


Solution 1:

Based on what I understand from your question, you are trying to filter the document with sizes is not an empty array.

You don't need $unwind stage but a $match stage.

db.collection.aggregate([
  {
    $match: {
      sizes: {
        $ne: []
      }
    }
  }
])

Sample Mongo Playground 1


Or

db.collection.aggregate([
  {
    $match: {
      $expr: {
        $ne: [
          {
            "$size": "$sizes"
          },
          0
        ]
      }
    }
  }
])

Sample Mongo Playground 2

Solution 2:

how about this instead of $unwind:

db.inventory2.aggregate([
  {
      $addFields : {
          "sizeCount" : {$size: "$sizes"}
      }
  },
  {$match: {"sizeCount" : {$gt: 0}}},
  {$project: {"sizeCount" : 0}}
])