Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB - Split an array into several multiple docs & replace existing doc with array's objects

I have one big json document in collection like this:

{
  "_id": {
    "$oid": "5e7a50e7f1d41b3ea05aa46e"
  },
  "response": {
    "count": 2,
    "items": [
      {
        "id": 1,
        "first_name": "Unknown",
        "last_name": "Unknown",
        "is_closed": false,
        "can_access_closed": true,
        "photo": "1.jpg",
        "track_code": "d9e2ca2eG4GbHAQSwz8Ne4WBiVx"
      },
      {
        "id": 2,
        "first_name": "Lorem",
        "last_name": "Ipsum",
        "is_closed": false,
        "can_access_closed": true,
        "photo": "2.jpg",
        "track_code": "23f1219a7j1xyWba69jz7p"
      }
    ]
  }
}

How I can split "items" by individual objects (for example by id in items) in the collection? As a result I want to have something like:

Object #1

{
  "_id": {
    "$oid": "5e7a50e7f1d41b3ea05aa46e"
  },
  "id": 1,
  "first_name": "Unknown",
  "last_name": "Unknown",
  "is_closed": false,
  "can_access_closed": true,
  "photo": "1.jpg",
  "track_code": "d9e2ca2eG4GbHAQSwz8Ne4WBiVx"
}

Object #2

{
  "_id": {
    "$oid": "ae2a40e7ffd41b3ea05aa46e"
  },
  "id": 2,
  "first_name": "Lorem",
  "last_name": "Ipsum",
  "is_closed": false,
  "can_access_closed": true,
  "photo": "2.jpg",
  "track_code": "23f1219a7j1xyWba69jz7p"
}

I can’t understand how to look for this in the documentation.

like image 704
humanbeing Avatar asked Sep 18 '25 04:09

humanbeing


1 Answers

You can try below query, with this your result can have more no.of docs than actual number in collection as we're exploding items array :

db.collection.aggregate([
  /** Adds '_id' field to each object inside items array, this can be done after 'unwind',
   *  if it's done after 'unwind' no.of docs to be iterated in 'unwind' is more, So better be done as first stage*/
  {
    $addFields: {
      "response.items._id": "$_id"
    }
  },
  /** Unwind items array, will exclude docs where items is not an array/doesn't exists */
  {
    $unwind: "$response.items"
  },
  /** Replace 'response.items' object as new root(document) */
  {
    $replaceRoot: {
      newRoot: "$response.items"
    }
  }
])

Test : MongoDB-Playground

Ref : aggregation-pipeline

like image 100
whoami - fakeFaceTrueSoul Avatar answered Sep 19 '25 17:09

whoami - fakeFaceTrueSoul