mongoose - How to manipulate/remove the sub-documents in MongoDB through MongooseJS? -


i have following schemas:

//define suberschema var suberschema = new schema({     _id: {         type: schema.types.objectid,         required: true     },     constraints: [constraintschema] });  //define spaceinfoschema var spaceinfoschema = new schema({     spacename: string,     subers: [suberschema],     _id: {     type: schema.types.objectid,     required: true    } }); 

i want manipulate/get subdocs when use following code, operates parentdocs.

  • this returns array subers. should suber specified id?

spaceinfomodel.find({"_id": spaceid,"subers._id": userid}, "subers", callback);

  • this removes whole document. should remove suber specified id?

spaceinfomodel.remove({"_id": spaceid,"subers._id": userid}, callback);

thanks in advance.

find() return documents collection called on. in example spaceinfomodel. query: spaceinfomodel.find({"_id": spaceid,"subers._id": userid}, "subers", callback); checking document in spaceinfomodel's collection matches id of spaceid , has sub-doc id of userid. if matching documents found returned array callback function.

at point can use helper function id() retrieve sub-doc:

// using findone match findbyid spaceinfomodel.findone({"_id": spaceid,"subers._id": userid}, 'subers').exec().then(function(spaceinfo) {   // spaceinfo.subers entire sub-doc array   return spaceinfo.subers.id(userid); }).then(function(suber) {   // suber }).then(null, function(err) { ... }); 

this has unfortunate side effect of returning sub-docs can prune down one. more efficient way have mongo pare down sub-doc array before returning parent doc. $elemmatch projection operator can used this.

spaceinfomodel.findbyid(spaceid).select({subers: {$elemmatch: {_id: userid}}}).exec().then(function(spaceinfo) {   // spaceinfo.subers array of matching sub-doc   return spaceinfo.subers.id(userid); }).then(function(suber) {   // suber }).then(null, function(err) { ... }); 

going beyond explore using aggregate pipeline unwind document sub-docs don't believe there gain on using elemmatch().

to remove sub-doc can done in similar manner. first approach requires retrieving entire array down , modifying locally pull() before saving monogodb.

spaceinfomodel.findone({"_id": spaceid,"subers._id": userid}, 'subers').exec().then(function(spaceinfo) {   // spaceinfo.subers entire sub-doc array   // remove matching id   spaceinfo.subers.pull({_id: userid});    // commit mongodb   return spaceinfo.save(); }).then(function() {   ... }).then(null, function(err) { ... }); 

again, done more efficiently directly on mongodb server.

spaceinfomodel.findbyidandupdate(spaceid, {$pull: {subers: {_id: userid}}}).select({subers: {$elemmatch: {_id: userid}}}).exec().then(function(spaceinfo) {   // spaceinfo.subers array of matching sub-doc   // original doc returned removed sub-doc on success   return spaceinfo.subers.id(userid); }).then(function(suber) {   // suber }).then(null, function(err) { ... }); 

note: $elemmatch used return sub-doc removed. if don't care simplify to:

spaceinfomodel.findbyidandupdate(spaceid, {$pull: {subers: {_id: userid}}}).exec().then(function(spaceinfo) {   ... }).then(null, function(err) { ... }); 

Comments

Popular posts from this blog

javascript - Using jquery append to add option values into a select element not working -

Android soft keyboard reverts to default keyboard on orientation change -

Rendering JButton to get the JCheckBox behavior in a JTable by using images does not update my table -