Desired Behaviour
I am trying to update the position
property of each object in an array of objects when one of their positions changes. For example, object with position 5
is moved to position 0
and therefore other objects' positions must also change.
I haven't been able to find an "array iterator" for MongoDB so have been trying to approach the problem from other angles but I think I am over-complicating it.
Schema
statements: [
{
"position": 0,
"id": "a"
},
{
"position": 1,
"id": "t"
},
{
"position": 2,
"id": "z"
},
{
"position": 3,
"id": "q"
},
{
"position": 4,
"id": "l"
},
{
"position": 5,
"id": "b"
}
]
Frontend Scenario
Figure A: Starting state of ordered divs
Figure B: Changed state of ordered divs (statement
5has been moved to position
0)
What I've Tried
Pseudo Code
I think the logic can be expressed as:
The objects position will change from the old_position to the new_position by an arbitrary amount of places.
If the reposition_direction is backwards, all objects with position greater than or equal to the new_position should increment (except for the object being moved which should be assigned the new_position)
If the reposition_direction is forwards, all objects with position less than or equal to the new_position should decrement (except for the object being moved which should be assigned the new_position)
(update: this logic is incorrect, working logic added to answer)
This is what I have so far:
if (reposition_direction === "backwards") {
var new_filter = { _id: o_id, "statements.position": { $gte: new_position } };
var new_update = { $inc: { "statements.$[elem].position": 1 } };
var array_filters = { "arrayFilters": [{ "elem.position": { $gte: new_position } }], "multi": true };
} else if (reposition_direction === "forwards") {
var new_filter = { _id: o_id, "statements.position": { $lte: new_position } };
var new_update = { $inc: { "statements.$[elem].position": -1 } };
var array_filters = { "arrayFilters": [{ "elem.position": { $lte: new_position } }], "multi": true };
}
collection.updateOne(new_filter, new_update, array_filters, function(err, doc) {
if (err) {
res.send(err);
} else {
res.json({ response: "hurrah" });
}
});