我想使用此查询从数组中删除嵌入对象。 它工作正常,但结果总是1.无论是否拉出数组元素。 这使得很难以适当的方式响应请求。
db.clients.update({_id: someId}, {$pull: {someArray: {id: req.params.id}}}, function(err, result) {
if (err) return next(err);
res.json(result);
});
Q)当没有拉出元素时,有没有办法让这个查询返回例如null或0?
答案 0 :(得分:3)
虽然MongoDB 2.6中有一些变化,但大多数驱动程序使用的实现仍然是从稍微不恰当的名称.getLastError()
调用中获得的“遗留”写入关注操作。
这里的一个已知问题是,只要更新语句“匹配”文档,那么获得的结果将等于“匹配”的数量,无论操作是否实际修改了文档。因此, $pull
和 $addToSet
等操作实际上可能无法对文档内容执行任何操作,其中“pull”查询的元素不会存在,或已经存在“addToSet”。
shell中有WriteResult(实际上现在在所有驱动程序中都有),但这里是混乱的步骤。驱动程序中实现的.update()
命令和shell实际上并不相同。在shell中,此方法实际上包含"Bulk Operations API"方法,并且在连接到功能强大的服务器时将尝试使用这些方法,并且只有在服务器不支持时才会回退到遗留实现。
出于这个原因,您目前需要在应用程序中构建相同类型的逻辑,否则只需使用您的应用程序可能永远不会实际连接到2.6版本以下的服务器节点并且仅使用批量API方法:< / p>
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方法中“真正发生的事情”。返回的“写入结果”将准确反映匹配的文档数量和“已修改”的数字。因此,如果没有实际更改,则“modified”包含0。
但必须直接使用这些方法。除非其他人想在更高级别的API上执行此操作以提供shell现在所执行的相同类型的抽象,否则原始方法不会更改以保持向后兼容性。
答案 1 :(得分:0)
你使用哪种mongo版本?对于版本2.6,更新会返回一个 WriteResult 对象,其中包含更新操作的状态,如mongo documentarion
中所示。