Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I atomically reorder array items in MongoDB?

Tags:

php

mongodb

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!

like image 677
Ruben S Avatar asked Feb 25 '26 06:02

Ruben S


1 Answers

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":

  1. Fetch the object.
  2. Modify the object locally.
  3. Send an update request that says "update the object to this new value if it still matches its old value".
like image 61
Stennie Avatar answered Feb 27 '26 19:02

Stennie



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!