2

Imagine you have this structure:

db.objecthierarchy.insertMany([
    {_id : 0,  children : [1,2,3]},
    {_id : 1,  children : [4,5]},
    {_id : 2,  children : [6]},
    {_id : 3,  children : []},
    {_id : 4,  children : [7]},
    {_id : 5,  children : [8,9]},
    {_id : 6,  children : [123,12,512,13]},
    {_id : 7,  children : []},
    {_id : 8,  children : [10]},
    {_id : 9,  children : []},
    {_id : 10, children : []},       
 ]);

Adding to the end of one of the children arrays is simple. This will add 6 to the end of the children list with 12 in it (object numbers are unique so only appear once as a child):

db.objecthierarchy.update(
  { children: 12 },
  {   
      $push: {children: 6},
  },
 true);

Similarly, if the position of "12" (say it's at 2nd position) is known as a constant, it's easy to insert say "7" after it like this:

db.objecthierarchy.update(
  { children: 12 },
  {   
      $push: {children: { $each: [7], $position: 2}}, 
  },
 true);

BUT I want to be able to insert a number into a 'children' array after or before an element already that is already in the array. I don't know the index up front and don't want to do a separate operation to get it (and lose the get-and-set atomicity as a result).

Something like this springs to mind but you can't call indexOfArray and pass it into $position so it doesn't work:

db.objecthierarchy.update(
  { children: 12 },
  {   
      $push: {children: { $each: [7],
          $position:  $indexOfArray: [ "$children", 12 ]  }},
  },
 true);

Is this something likely to be added in the near future ?

Alternatively, any thoughts on how to achieve this in an atomic/server-side single update would be appreciated, or an alternative model for trees where atomic updates along these lines would work (although I do need other access to the tree too).

Ian Fallon
  • 21
  • 2

0 Answers0