2014-10-01 100 views
0

我想使用此查询从数组中删除嵌入对象。 它工作正常,但结果始终为1.无论是否拉出数组元素。 这使得很难以正确的方式回应请求。

db.clients.update({_id: someId}, {$pull: {someArray: {id: req.params.id}}}, function(err, result) { 
    if (err) return next(err); 
    res.json(result); 
}); 

Q)有没有一种方法,使例如零或零该查询返回的时候不拉的元素?

回答

2

看到虽然有MongoDB中2.6的一些变化,大多数驱动程序使用的执行仍是“遗留”写关注操作从稍微不恰当地命名为.getLastError()的调用中获得。

这是一个知道的问题,只要更新语句“匹配”一个文档,那么获得的结果将等于“匹配”的数量,而不管操作是否实际修改了文档。因此,如$pull$addToSet操作实际上可能没有做任何事情来这里或者通过查询元素的“拉”不存在,或者已经存在了一个“addToSet”的文档内容。

有一个在shell中可用的WriteResult(事实上在所有的驱动程序中),但这里是混淆的地方。在驱动程序和shell中实现的.update()命令实际上并不相同。在shell中,此方法实际上包装了"Bulk Operations API"方法,并且会在连接到有能力的服务器时尝试使用这些方法,并且只在服务器不可用时才回退到传统实现。

因此,您目前需要在您的应用程序中构建相同类型的逻辑,否则只能承受您的应用程序可能永远不会实际连接到2.6版本以下的服务器节点,并独占使用批量API方法:

db.collection('testcol',function(err,col) { 
    if (err) throw err; 

    var bulk = col.initializeOrderedBulkOp(); 

    bulk.find({ "_id": someId}).updateOne({ 
     "$pull": { 
      "someArray": { "id": req.params.id } 
     } 
    }); 
    bulk.execute(function(err,result) { 
    if (err) throw err; 
    console.log(result.toJSON()); 
    }); 
}); 

这就是现代MongoDB发布的shell方法中“底层”所发生的事情。返回的“写入结果”将准确反映匹配的文档数量和“修改”数量。因此,如果没有任何变化,“修改”包含0.

但是,您必须必须直接使用该方法。除非有人希望在更高级别的API上提供,以提供与shell现在相同的抽象,否则原始方法不会改变以保持向后兼容性。

+0

谢谢尼尔!你怎么知道这一切?谷歌没有给我任何关于这一点。你是一个真正的MongoDB头像。 – 2014-10-02 07:26:51

+0

@AndersÖstman您可以通过做一些简单的事情来说明最好的方式,比如'db.collecition。更新'没有方括号'()'在函数的末尾。这基本上记录了函数内容,它在shell中只是JavaScript。 – 2014-10-02 07:43:49

+0

这真的很好! **如果**我使用简单的mongodb模块...它不适用于Mongoskin。 – 2014-10-02 14:01:10

0

你正在使用哪个mongo版本?对于2.6版本的更新返回写结果对象更新操作的状态,您可以在mongo documentarion

+0

使用2.6的Im。我知道writeResult对象。我已经通过在回调中命名了它,例如:function(err,result,writeResult)。不幸的是,如果一个数组元素被拉或不拉,这个对象没有区别。 – 2014-10-01 17:06:55

+0

您是否尝试将更新返回分配给变量并进行检查,如下所示:var result = db.clients.update({...}); – lombardo 2014-10-01 17:12:47

+0

我还没有。尽管它似乎是一个奇怪的方式来处理它,我明天会尝试这个。 – 2014-10-01 17:25:53