Creating a fixed-size array in a MongoDB document can be less than straightforward. Mongo doesn’t support declaring an array’s maximum size or limiting the size of the array when $pushing onto an array (see SERVER-991). The solution I had initially thought up was to create new documents with the fixed-size array filled with empty values. Writes would then use a $push to add a new item and $pop : -1 to remove the first item, keeping the array the same size as when it was first created. However, I learned that MongoDB will not let you use the same field name in two operators in the same command (see SERVER-2643):
Well, that sucks. How about breaking out the $push and $pop into two separate commands:
The functionality is the same but, since it’s not within one command, a few potential problems have been introduced.
The $push could happen without the $pop meaning the array could grow longer than intended. This shouldn’t happen very often: only if there’s an error with the $push, the database connection is lost or the code dies between the commands. The code that handles the reads can log a warning when it encounters a document with an oversized array and then grab only the last n items from the array (see the $slice operator).
Having a few extra items in the array shouldn’t be a problem, as long as it doesn’t get out of hand. However, if the $pop occurs without the $push the array may become smaller than desired, possibly losing data. The update should only remove items from the array if it’s larger than the minimum required number of elements. MongoDB has a $size operator but it only allows matching an exact number of elements, not a range. The solution is to add a size field that gets incremented with a $push and decremented with a $pop. The criteria of the $pop can then use the size field as a check.
In addition, if safe writes can be used, the return value of the $push command can be checked to see if the write succeeded before the $pop is issued, ensuring array can only grow too large.
This all seems a bit convoluted to simply get fixed-sized arrays in MongoDB. Hopefully 10gen will add them as a native feature soon. If these features are important to you, please vote on SERVER-991 and SERVER-1050 on 10gen’s JIRA.