Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Updating multiple documents with different values

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.

like image 893
Jonathan Nielsen Avatar asked Aug 22 '16 14:08

Jonathan Nielsen


People also ask

How do I update multiple values in MongoDB?

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.

Which command is used to update all documents in a collection?

Use the db. collection. updateMany() to update all documents that match a specified filter.

Which option should be used to update all the documents with the specified condition in the MongoDB query?

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.


1 Answers

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);
like image 82
chridam Avatar answered Oct 23 '22 03:10

chridam