I'm using jquery ui's sortable function (source) to re-arrange elements. I've built custom callbacks to create an list of those elements. So when i move an element, all elements is given a new position id. It could look like this:
[{
    id_of_element_in_database: 12,
    new_position: 0
}, {
    id_of_element_in_database: 16,
    new_position: 1
}, {
    id_of_element_in_database: 14,
    new_position: 2
}]
I'm sending this list to my back-end by doing a simple Ajax post
$.post('/position', { data: list });
Route
router.post('/position', (req, res) => {
    console.log(req.body.data); // This prints the array of objects above.
});
Schema
mongoose.Schema({
    id: Number,
    position: Number,
    ...
});
Now I can't figure out how to change the position of all documents effectively. Creating a crappy loop of the array and doing multiple database-requests can't be the best approach.
I've tried that here and this feels so wrong.
for (let i in req.body.data) {
    collection.update({ id: req.body.data[i].id }, { position: req.body.data[i].position });
There must be something else i can do to achieve this. I've tried google without any luck.
Update Multiple Fields of a Single Document. We can use $set and $inc operators to update any field in MongoDB. The $set operator will set the newly specified value while the $inc operator will increase the value by a specified value.
Use the db. collection. updateMany() to update all documents that match a specified filter.
By default, the db. collection. update() method updates a single document. Include the option multi: true to update all documents that match the query criteria.
You could try the bulkWrite API to carry out the updates in a better way without multiple requests to the server:
var callback = function(err, r){
    console.log(r.matchedCount);
    console.log(r.modifiedCount);
}
// Initialise the bulk operations array
var ops = req.body.data.map(function (item) { 
    return { 
        "updateOne": { 
            "filter": { 
                "id": parseInt(item.id),
                "position": { "$ne": parseInt(item.position) }
            },              
            "update": { "$set": { "position": parseInt(item.position) } } 
        }         
    }    
});
// Get the underlying collection via the native node.js driver collection object
Model.collection.bulkWrite(ops, callback);
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With