【问题标题】:Getting error "pipeline element 3 is not an object error", while trying to find & update using aggregate尝试使用聚合查找和更新时出现错误“管道元素 3 不是对象错误”
【发布时间】:2016-10-08 10:41:25
【问题描述】:

我正在使用node js mongodb driver 并尝试更新文档中对象数组内的object array

文档集合的schema是这样的:

我想要什么:

要使用order no = 1 & items.qty=2 & tax rate = 25 收集,请更新tax to "cst" & taxratetype to "flat"

我尝试了什么:

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);
});

}
});

目前我正在使用 db.eval 从节点运行此脚本,但稍后会在我完成相同操作后更改它。

出现此错误:

{"name":"MongoError","message":"Error: command failed: {\n\t\"ok\" : 0,\n\t\"errmsg\" : \"管道元素 3 不是 object\",\n\t\"code\" : 15942\n} : 聚合失败 :\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":"错误: 命令失败:{\n\t\"ok\" : 0,\n\t\"errmsg\" : \"管道元素 3 不是对象\",\n\t\"code\" : 15942\n} : 聚合失败 :\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}

我从这个问题知道https://jira.mongodb.org/browse/SERVER-831 我不能使用直接更新命令,因此尝试了这种解决方法。 任何其他此类更新的方法对我来说也很好。

编辑: 根据@titi23 给出的答案,我曾尝试在函数内部使用 [] 。 它没有给我任何错误,但是我的值也没有得到更新。

【问题讨论】:

    标签: node.js mongodb aggregation-framework


    【解决方案1】:

    查询中的两个问题:

    1) 您在aggregate 查询中缺少[]

    2) 更新方法不需要税率条款。它将找到嵌套文档,并且聚合中的索引将用于更新目的。

    有关如何使用它的更多信息,请参阅aggregate-definition

    语法 - db.collection.aggregate(管道,选项)

    pipeline - 数组 - 数据聚合操作或阶段的序列。

    尝试以下方法:-

    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);
        });
      }
    });
    

    它不应该抛出错误。

    编辑:- 对聚合执行toArray(),看看是否有帮助。已经更新了查询。

    【讨论】:

    • 我也试过这个,它没有给我任何错误,但它没有更新值..
    • 尝试使用{ '$items.qty' : 2} 而不是使用{ 'items.qty' : 2}。让我知道它是否有效
    • 它给出错误:BadValue: unknown top level operator: $items
    • 使用此要求编辑您的问题。这个答案是针对您最初的问题。让我看看我能帮你什么。
    • 您能否运行我已更新的聚合查询并告诉我,它是否找到任何记录?我还添加了控制台。让我知道控制台是否提供任何记录。
    猜你喜欢
    • 2018-09-21
    • 1970-01-01
    • 1970-01-01
    • 2021-06-12
    • 2012-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-10
    相关资源
    最近更新 更多