Abdul Rehman Sayed Abdul Rehman Sayed - 5 months ago 86
Node.js Question

Getting error "pipeline element 3 is not an object error", while trying to find & update using aggregate

I am using

node js mongodb driver
& trying to update an
object array
inside an object array in a document.

The schema of the document collection is this :

enter image description here

What I Want :

For collection with
order no = 1 & items.qty=2 & tax rate = 25
, update the
tax to "cst" & taxratetype to "flat"
.

What I Tried :

db.OrderInfo.aggregate(
{$match:{"orderno":"1"}},
{$unwind:'$items'},
{ $match: { 'items.qty' : 2}
},function(err,result1){
if(err){
throw(err);
}else{
indexes = result1[0].items.taxes.map(function(obj, index) {
if(obj.taxrate == 25) {
return index;
}
}).filter(isFinite);

var updateData = {};
updateData["items.$.taxes."+indexes[0]+".tax"]="cst";
updateData["items.$.taxes."+indexes[0]+".taxratetype"]="flat";


db.OrderInfo.update({ "orderno":"1",'items.qty': 2,'items.taxes.taxrate': 25 },{$set: updateData },function(err,result2){
console.log(result2);
});

}
});





Currently I am using db.eval to run this script from node but later will change it once I accomplish the same.

Getting this Error :


{"name":"MongoError","message":"Error: command failed: {\n\t\"ok\" :
0,\n\t\"errmsg\" : \"pipeline element 3 is not an
object\",\n\t\"code\" : 15942\n} : aggregate failed
:\n_getErrorWithCode@src/mongo/shell/utils.js:25:13\ndoassert@src/mongo/shell/assert.js:13:14\nassert.commandWorked@src/mongo/shell/assert.js:267:5\nDBCollection.prototype.aggregate@src/mongo/shell/collection.js:1312:5\n_funcs1@:1:31\n","ok":0,"errmsg":"Error:
command failed: {\n\t\"ok\" : 0,\n\t\"errmsg\" : \"pipeline element 3
is not an object\",\n\t\"code\" : 15942\n} : aggregate failed
:\n_getErrorWithCode@src/mongo/shell/utils.js:25:13\ndoassert@src/mongo/shell/assert.js:13:14\nassert.commandWorked@src/mongo/shell/assert.js:267:5\nDBCollection.prototype.aggregate@src/mongo/shell/collection.js:1312:5\n_funcs1@:1:31\n","code":139}


I know from this issue https://jira.mongodb.org/browse/SERVER-831
that I cannot use a direct update command & hence trying this workaround.
Any other approach for such updates is also fine with me.

EDIT :
As per answer given by @titi23, I had tried using [] also inside function.
It did not gave me any error but, my values also did not get updated.

Answer

Two problems in the query :

1) You are missing [] in the aggregate query.

2) The update method does not need the tax rate clause. It will find the nested document & the index from aggregate would serve the purpose in update.

Refer aggregate-definition for more info on how to use it.

Syntax - db.collection.aggregate(pipeline, options)

pipeline - array - A sequence of data aggregation operations or stages.

Try the following:-

db.OrderInfo.aggregate([
{$match:{"orderno":"1"}},
{$unwind:'$items'},
{ $match: { 'items.qty' : 2} }]).toArray(
function(err,result1){
if(err){
    throw(err);
}
else{
   console.log(result[0]); //See is there any record here
   indexes = result1[0].items.taxes.map(function(obj, index) {
  if(obj.taxrate == 25) {
  return index;
  }
 }).filter(isFinite);

var updateData = {};
updateData["items.$.taxes."+indexes[0]+".tax"]="cst";
updateData["items.$.taxes."+indexes[0]+".taxratetype"]="flat";


 db.OrderInfo.update({ "orderno":"1",'items.qty': 2}, /*Remove the tax rate clause from here..*/
      {$set: updateData },function(err,result2){
        console.log(result2);
    });
  }
});

It should not throw the error.

EDIT:- Do toArray() with the aggregate, see if it helps. Updated the query already.

Comments