node.js - Node, MongoDB : Incrementing values of items in array with range query -


i have array of categories under users collection in mongodb.

basically there drag , drop menu of categories in front end, when drag&drop happens want update database. since not possible move items in array, decided give them position value "pos" in mongodb , sort them later in angularjs.

categories: [      {          "_id" : objectid("5776782a57c9580256536656"),          "title" : "cars",          "url" : "cars",          "pos" : 0      },      {          "_id" : objectid("5776786afdcd6ed056edff25"),          "title" : "photography",          "url" : "photography",          "nodes" : [               {                  "_id" : objectid("57767870fdcd6ed056edff26"),                  "title" : "landscape",                  "url" : "landscape"              }          ],          "pos" : 1      },      {          "_id" : objectid("adf9845782578a376161d079"),          "title" : "travel",          "url" : "travel",          "pos" : 2      }  ]

i'm using nodejs-express server , here code move categories.

  • oldindex : position of category before moving
  • newindex : new position of category after moving
  • userid : users object id

    if (newindex>oldindex){          db.collection('users').updateone({ "_id": userid, "categories.pos": { $gte: oldindex, $lt: newindex } }, { $inc : { "categories.$.pos" : -1 } }, function (err, res) {              console.log(res);              if (err) callback(0)              else {                  db.collection('users').updateone(filter, { $set :  cdata }, function (err, res) {                      if (err) callback(0);                      callback(1);                  });              }          });      } else {          db.collection('users').updateone({ "_id": userid, "categories.pos": { $gt: newindex, $lte: oldindex  } }, { $inc : { "categories.$.pos" : 1 } }, function (err, res) {              console.log(res);              if (err) callback(0)              else {                  db.collection('users').updateone(filter, { $set :  cdata }, function (err, res) {                      if (err) callback(0);                      callback(1);                  });              }          });      }

basically, code meant this

if (newindex > oldindex)

  • category - 0 (oldindex)
  • category b - 1
  • category c - 2
  • category d - 3

to move index 2

  • category b - 0 (-1)
  • category c - 1 (-1)
  • category - 2 (newindex)
  • category d - 3 (0)

and other way around

if (oldindex > newindex)

  • category - 0
  • category b - 1
  • category c - 2 (oldindex)
  • category d - 3

to move c index 0

  • category c - 0 (newindex)
  • category - 1 (+1)
  • category b - 2 (+1)
  • category d - 3 (0)

in case, can't run find query see & troubleshoot results of query..

with number of categories, query updates 1 value.

i guess need new pair of eyes.

thank you.

mongodb keeps order of array. remove element in array , reinsert element correct position using $position

query remove element:

db.getcollection('users').update({         "_id" : idusers     },     {         $pull: {             categories: {                 field: foo //your field grep element             }         } }) 

and query set element @ new index:

db.getcollection('users').update(     {         "_id" : idusers     },     {         $push: {             categories: {                // set 1 element in $each, enable use $position                 $each: [{                     "title" : "photography",                     "url" : "photography",                     "nodes" : [{                             "_id" : objectid("57767870fdcd6ed056edff26"),                             "title" : "landscape",                             "url" : "landscape"                     }]                 }],                 $position: newindex             }         }     } ) 

i made manually test , seem work


Comments