Home > Blockchain >  Unwind object array but preserve its parent
Unwind object array but preserve its parent

Time:04-08

I want to unwind some data, but preserve the parent. I am getting the whole flattened objects, but missing the first one. I want to keep that one. How can I do such a thing?

My documents:

    [
      {
        "key": 1,
        "keys": [
          {
            key: 3
          },
          {
            key: 4
          },
          {
            key: 5
          },
          
        ]
      },
      {
        "key": 2
      }
    ]

And after performing this:

db.collection.aggregate([
  {
    "$match": {},
    
  },
  {
    "$unwind": {
      path: "$keys",
      preserveNullAndEmptyArrays: true,
      
    }
  },
  {
    "$replaceWith": {
      "$mergeObjects": [
        "$$ROOT",
        "$keys"
      ]
    }
  }
])

I am getting this:

[
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "key": 3,
    "keys": {
      "key": 3
    }
  },
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "key": 4,
    "keys": {
      "key": 4
    }
  },
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "key": 5,
    "keys": {
      "key": 5
    }
  },
  {
    "_id": ObjectId("5a934e000102030405000001"),
    "key": 2
  }
]

But it should be like:

{ key: 1},
{ key: 2},
{ key: 3},
{ key: 4},
{ key: 5},

Is that possible to accomplish? And is this possible to accomplish with large data ( $group stage is giving me memory overflow)?

CodePudding user response:

Query

  • adds the key inside the keys array (if keys is not array, keys will start with [])
  • unwind keys
  • replaceRoot
  • sort

PlayMongo

aggregate(
[{"$set": 
   {"keys": 
     {"$concatArrays": 
       [{"$cond": [{"$isArray": ["$keys"]}, "$keys", []]},
         [{"key": "$key"}]]}}},
 {"$unwind": "$keys"},
 {"$replaceRoot": {"newRoot": "$keys"}},
 {"$sort": {"key": 1}}])
  • Related