I'd like to have push add at the beginning of my set rather than appended to the end when I do a mongo $push.

Is it possible to do an atomic push update that adds elements as the first rather than the last?


2014 update: yes you can.

Solution 1

As of MongoDB v2.5.3, there is a new $position operator that you can include along with the $each operator as part of your $push query to specify the location in the array at which you would like to insert a value.

Here's an example from the docs page to add the elements 20 and 30 at the array index of 2::

db.students.update( { _id: 1 },
                    { $push: { scores: {
                                         $each: [ 20, 30 ],
                                         $position: 2
                                       }
                             }
                    }
                  )

Reference: http://docs.mongodb.org/master/reference/operator/update/position/#up._S_position

Solution 2

Use negative index with $set for prepend, tested in mongo v2.2:

> db.test.insert({'array': [4, 5, 6]})
> db.test.find()
{ "_id" : ObjectId("513ad0f8afdfe1e6736e49eb"),
  "array" : [ 4, 5, 6 ] }

//prepend 3
> db.test.update({"_id" : ObjectId("513ad0f8afdfe1e6736e49eb")}, 
                 {'$set': {'array.-1':     3}})
> db.test.find()
{ "_id" : ObjectId("513ad0f8afdfe1e6736e49eb"), 
  "array" : [ 3, 4, 5, 6 ] }

//prepend 2
> db.test.update({"_id" : ObjectId("513ad0f8afdfe1e6736e49eb")}, 
                 {'$set': {'array.-1':     2}})
> db.test.find()
{ "_id" : ObjectId("513ad0f8afdfe1e6736e49eb"), 
  "array" : [ 2, 3, 4, 5, 6 ] }

//prepend 1
> db.test.update({"_id" : ObjectId("513ad0f8afdfe1e6736e49eb")}, 
                 {'$set': {'array.-1':     1}})
> db.test.find()
{ "_id" : ObjectId("513ad0f8afdfe1e6736e49eb"), 
  "array" : [ 1, 2, 3, 4, 5, 6 ] }

Solution 3

A similar question was asked a few days ago. Unfortunately, the short answer is, "no", but there is an open request for this feature.
https://jira.mongodb.org/browse/SERVER-2191 - "$push() to front of array"

There is some more information as well as a possible work-around on the other thread: "Use MongoDB array as stack" - Use MongoDB array as stack

Hopefully the above will be useful and help you to find an acceptable work-around.