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).