I have a playlists collection. Each document in the collection contains an entries field, that is an array.
How can I change the order of entries in a playlist, atomically?
(e.g. If another user tries at the same time to $push a new entry, I want to make sure that the new entry is $pushed only after the reordering has happened)
If I do a find(), then reorder in PHP, then update(), I might lose the new $pushed entry if the operation is not atomic.
This is a sample playlist object:
{
"_id" : "playlist1",
"title" : "Playlist One",
"entries" : [
{
"class" : "song",
"identifier" : "song1"
},
{
"class" : "song",
"identifier" : "song2"
},
{
"class" : "song",
"identifier" : "song3"
}
]
}
Edit:
I think I found a possible solution, using execute():
Running JavaScript in the database takes a write lock, meaning it blocks other operations.
(from http://php.net/manual/en/mongodb.execute.php)
I just need to execute the code (find() + reorder() + update()) on the MongoDB Server.
Still, if you have another idea that doesn't involve "code within a string" (e.g. $func = "function() { do_something(); return \"something else\" }"), please share it.
Thanks!
Using eval() to block operations is a side effect of the current implementation, not a feature to rely on.
The MongoDB wiki has a page with information on Atomic Operations.
A relevant strategy for your use case would be "update if current":
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