I need to be able to increment and decrement the position of an element of an array in a MongoDB
object.
I looked at the <update>
API in the MongoDB API but could not find anything to let me do so.
I am trying to use findOneAndUpdate
through Mongoose
and I know the index of the element I am trying to shift up or down.
An example of the array item of base64
encoded images:
{
images: [
"img1",
"img2",
"img3"
]
}
And I would like to move, for example "img2", up or down (but "image" should not be able to pushed up since there is nowhere to go).
If I wanted to push "img2" up then the result would be:
{
images: [
"img2",
"img1",
"img3"
]
}
It doesn't matter if I achieve this through changing the index, swapping, or pushing up/down.
Like @blakes-seven said, you have two ways to do it:
Grabing, updating and pushing
db.images.find({ _id: '' }, { images : 1 })
.then(function(img) {
var tmpImg = img.images[0];
img.images[0] = img.images[1];
img.images[1] = tmpImg;
db.images.update({ _id: img._id }, { $set: { images: img.images } });
})
Updating directly (if you have the image on the client and know the indexes), using $position
db.images.update({ _id: '' }, { $push: { images: { $each: ['img2'] }, $position: 0 } } } )
.then(function() {
db.images.update({ _id: '' }, {$unset: {'images.2': 1}})
});
https://docs.mongodb.org/manual/reference/operator/update/position/
However, I think you should redesign the way you stores your images, using by example a virtual ordering:
{
images: [
{ base64: 'img1', order: 0, _id: 'img1' },
{ base64: 'img2', order: 1, _id: 'img2' },
{ base64: 'img3', order: 2, _id: 'img3' }
]
}
This way, you could order your images using a virtual order index, updating them using only the _id, or updating the whole collection by changing order of all img2, dropping or replacing an image, etc.