3

I have a list like this:

{ 
    arr: [
        { _id: 'a', val: 1 }, 
        { _id: 'b', val: 4 }, 
        { _id: 'd', val: 0 }, 
        { _id: 'c', val: 8 }
    ] 
}

And I need to put the element {_id: c} before the element {_id: d}. How can I do it with mongo? Of course, I can download the doc to my server, prepare it and upload the one to the mongo server. But I think, it's not a good way.

P.S: sorry, I need to move the element (push it to a new position and remove the one from old position)

Alex Ivashkin
  • 320
  • 1
  • 13
  • I think a easier way of doing that would be to make another id that you can more easily access, and sort by that id when you need to use the document. – DrakaSAN Jun 17 '16 at 12:36
  • Do you want to swap elements or to sort them? If you need to sort them there is a $sort option you may be able to use. – Soren Jun 17 '16 at 13:06
  • Has anyone found the solution ? – DecPK Sep 06 '20 at 08:10

2 Answers2

2

You can use the keyword $position to specify where in the array you want to insert the value. Use it when $pushing an element on and you'll be able to insert that element into a specific place in the array.

db.collection.update(
    {parameter: doc},
    {$push: {
        arr: {
            $each: [{_id: "c", val: 8}],
            $position: 2
        }
    })

This will push that object into position 2 of your array. If you're looking to manipulate the array by removing objects at specific points, you can refer to the answer I linked in the comments.

Community
  • 1
  • 1
Gibryon Bhojraj
  • 755
  • 5
  • 12
  • NIce, how does he remove the element in position 3? Maybe a working example would be good. – Soren Jun 17 '16 at 12:55
  • There are more ways to do that, using `$pull`. I don't know if you can specify a `$position` field within `$pull`, but there are other answers for that: http://stackoverflow.com/questions/4969768/removing-the-array-element-in-mongodb-based-on-the-position-of-element – Gibryon Bhojraj Jun 17 '16 at 13:00
  • And what about the document which is at position 2 – Shantanu Madane Jun 17 '16 at 13:17
  • `$push` won't remove the document at position 3, and OP didn't ask to remove it, so this code preserves the array and just inserts. But @Soren asked about removing the element at a certain position, so I included a link to do that with `$pull` – Gibryon Bhojraj Jun 17 '16 at 13:20
  • The author of this question specifically asked to shift the element from one position to another, not to push a new element. This is half right answer. – DecPK Sep 06 '20 at 08:09
0

Try This:

db.myCollection.find().forEach(function(doc){
        db.myCollection.update({_id: doc._id},
          {$set: {"arr.2": doc.arr[3], "arr.3": doc.arr[2]}})
    })
OR
You can Pull and then push those documents
Shantanu Madane
  • 617
  • 5
  • 14
  • >> Of course, I can download the doc to my server, prepare it and upload the one to the mongo server. But I think, it's not a good way. – Alex Ivashkin Jun 17 '16 at 12:57
  • Does the callback not copy this to the application rather than just work on the mongodb server? – Soren Jun 17 '16 at 12:58
  • @Soren yeap, but if I will work on the mongodb server I will block the main thread. – Alex Ivashkin Jun 17 '16 at 13:03
  • Not sure that is relevant, since the OP specifically wanted something that didn't copy the data across. – Soren Jun 17 '16 at 13:10