DecPK
DecPK

Reputation: 25408

How to shift element from one array position to another in MongoDB with mongoose?

I have got an array of objects in MongoDB and I was moving a particular element id (i.e 1) from its position to below element having id (i.e 2). So that we can get element with id as 2 -> 1 -> 3.

const arr = [
  {
    id: 1,
    name: 'foo'
  },
  {
    id: 2,
    name: 'bar'
  },
  {
    id: 3,
    name: 'zoo'
  }
]

What I've done is used $pull and $push but it gives ConflictingUpdateOperators and I don't know how to deal with it.

updatedPlan = await Plan.findOneAndUpdate(
        { _id: req.params.id },
        {
          $pull: {
                    "arr": {
                        id: 1
                    }
          },
          $push: {
                  "arr" : {
                    $each: [{ id: 1, name: 'foo'}],
                    $position: 1
                  }
          },
      );

Upvotes: 1

Views: 613

Answers (1)

mickl
mickl

Reputation: 49945

In MongoDB 4.2 or newer you can update a document with Aggregation Pipeline. Using simple $map on a $range of array indexes you can shuffle these indexes and use $arrayElemAt in order to build a new array:

db.col.update({ _id: req.params.id }, [
    {
        $set: {
            arr: {
                $map: {
                    input: { $range: [ 0, { $size: "$arr" } ] },
                    in: {
                        $let: {
                            vars: {
                                newIndex: {
                                    $switch: {
                                        branches: [
                                            { case: { "$eq": [ "$$this", 0 ] }, then: 1 },
                                            { case: { "$lte": [ "$$this", 1 ] }, then: { $subtract: [ "$$this", 1 ] } },
                                        ],
                                        default: "$$this"
                                    }
                                }
                            },
                            in: {
                                $arrayElemAt: [ "$arr", "$$newIndex" ]
                            }
                        }
                    }
                }
            }
        }
    }
])

Upvotes: 1

Related Questions