How to insert to the certain position in the array in the subdocument by using Mongoose an MongoDB 2.6

StackOverflow https://stackoverflow.com/questions/23083041

  •  04-07-2023
  •  | 
  •  

Question

A great explanation of how to use new $position operator of Mongodb 2.6 by using Mongoose was given in the answer to my question. The suggested solution works perfect for simple arrays. If array is in subdocument or each element of array is array the suggested solution doesn't work. I mean something like this:

List.collection.update(
{/*....*/},
{ "$push": {
    "subdocument.list": {
      "$each": [ 1, 2, 3 ],
      "$position": 0 }
    }
},function(err,NumAffected) {
  console.log("done");

});
List.collection.update(
{/*....*/},
{ "$push": {
    "list1.$.list2": {
      "$each": [ 1, 2, 3 ],
      "$position": 0 }
    }
},function(err,NumAffected) {
  console.log("done");

});
Was it helpful?

Solution 2

No sure what the issue is here:

db.list.insert({ "list": { "sub": [4] } })
db.list.update(
    {},
    { "$push": { "list.sub": { "$each": [1,2,3], "$position": 0 } } }
)

{ "list" : { "sub" : [ 1, 2, 3, 4 ] } }

So that works as expected.

And for the other example:

db.list.insert({
    outer: [
       {
           key: "a", 
           inner: [4]
       },
       {
           key: "b", 
           inner: [4]
       }
   ]
})

db.list.update(
    { "outer.key": "b" },
    { "$push": { 
        "outer.$.inner": { 
            "$each": [1,2,3], "$position": 0 
        }
    }}
)

Again is as expected:

{
    "outer" : [
            {
                    "key" : "a",
                    "inner" : [
                            4
                    ]
            },
            {
                    "key" : "b",
                    "inner" : [
                            1,
                            2,
                            3,
                            4
                    ]
            }
    ]
}

The interaction with specific drivers was already explained so there must be something different in the data, but if so then those statements are not valid.

And so exactly the same using Mongoose:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

mongoose.connect('mongodb://localhost/nodetest');

var listSchema = new Schema({

});

var List = mongoose.model( "List", listSchema );
var Other = mongoose.model( "Other", listSchema );

  List.collection.update(
    {},
    { "$push": {
    "list.sub": {
      "$each": [ 1, 2, 3 ],
      "$position": 0 }
    }
    },function(err,NumAffected) {
      console.log("done");

    }
  );


  Other.collection.update(
    { "outer.key": "b" },
    { "$push": {
        "outer.$.inner": {
            "$each": [ 1, 2, 3 ],
            "$position": 0
        }
    }},function(err,NumAffected) {
      console.log("done2")
    }
  );

OTHER TIPS

In the current Mongoose version (4.4.2) you can use position like this:

Foo.update(query.id,
    {
        $push: {
            arrayData: {
                $each: [{                       
                    date: new Date
                }], $position: 0 
            }
        }
    });

I have found the code in the MongooseJS Model.update that omits support for the $position modifier.

In version 3.8.8, line 1928-1941 of query.js:

      if ('$each' in val) {
        obj[key] = {
            $each: this._castUpdateVal(schema, val.$each, op)
        }

        if (val.$slice) {
          obj[key].$slice = val.$slice | 0;
        }

        if (val.$sort) {
          obj[key].$sort = val.$sort;
        }

      }

Here, obj[key] will be set to val.$each. You can see explicit support for setting the $slice & $sort modifiers, but the $position modifier will never be copied into obj[key].

So, although you may be able to by-pass the Model.update function of MongooseJS to directly access MongoDB's update function, it is clear that MongooseJS's Model.update function does not support the $position modifier.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top