How to write a mongodb query to move an array from one array field to another?

I have two fields in a mongodb document publish and draft with schema as:

publish: [[
            { type: String, required: true },
            { type: String, required: true }
        ]],
    

draft: [[
            { type: String, required: true },
            { type: String, required: true }
        ]]

and value look like this in db

"draft": [
    [
      "Panic 2",
      "63d2648d373f7fea3fa9d387_1681628752497"
    ],...
  ],
  "publish": [
    [
      "Ruins Exploration Gone Wrong!",
      "63d2648d373f7fea3fa9d387_1681628787816"
    ],
    [
      "Fresh Start",
      "63d2648d373f7fea3fa9d387_1681628805269"
    ],...
  ]

now i’m working on a query which can move the array
["Panic 2","63d2648d373f7fea3fa9d387_1681628752497"] from draft to publish but i only 63d2648d373f7fea3fa9d387_1681628752497 to achieve so. How should i frame my query

EDIT: I have tried some way and was able to pull the array from draft field but havent been able to push that array to publish with only the presence of id

>Solution :

Assume that the second element within the inner array is unique, you can perform the update with aggregation pipeline:

  1. $set

    selected – Filter the matching element for the id value from the draft array.

    draft – Filter the element to remove it (selected) from the draft array.

  2. $set

    published – Combine the selected array with published array.

    selected – Remove the selected field.

db.collection.update({
  "draft": {
    $elemMatch: {
      $elemMatch: {
        $eq: "63d2648d373f7fea3fa9d387_1681628752497"
      }
    }
  }
},
[
  {
    $set: {
      selected: {
        $filter: {
          input: "$draft",
          cond: {
            $eq: [
              {
                $arrayElemAt: [
                  "$$this",
                  1
                ]
              },
              "63d2648d373f7fea3fa9d387_1681628752497"
            ]
          }
        }
      },
      draft: {
        $filter: {
          input: "$draft",
          cond: {
            $ne: [
              {
                $arrayElemAt: [
                  "$$this",
                  1
                ]
              },
              "63d2648d373f7fea3fa9d387_1681628752497"
            ]
          }
        }
      }
    }
  },
  {
    $set: {
      publish: {
        $concatArrays: [
          "$publish",
          "$selected"
        ]
      },
      selected: "$$REMOVE"
    }
  }
])

Demo @ Mongo Playground

Leave a Reply