从集合的单个文档中的对象数组中删除单个对象

时间:2016-07-04 04:18:34

标签: node.js mongodb

我有一个问题,我正在努力相当一段时间。假装我的文件是这样的

{"owner":"princu7", "books":[{"name":"the alchemist"},  {"name":"the alchemist"}, {"name":"the alchemist"}].

现在,如果我必须根据名称的匹配从books数组中删除一个单独的元素,我该怎么办?我这样做了

var bookName="the alchemist";
var obj={"name":bookName}
db.collection("colName").update({"owner":"princu7"}, {$pull:{books:obj}}, {multi:false})

但问题是它删除了数组中名称与“炼金术士”匹配的所有条目。我想要的是这个

{"owner":"princu7", "books":[{"name":"the alchemist"},  {"name":"the alchemist"}

但我得到的是这个

{"owner":"princu7", "books":[]}

在阅读文档后,它说pull会删除所有匹配所需条件的实例,这也许就是为什么它会删除匹配条件的数组的所有其他条目。所以我该怎么做。谢谢阅读。感谢你的帮助。

3 个答案:

答案 0 :(得分:3)

看到此问题: https://jira.mongodb.org/browse/SERVER-1014

您无法在单次更新中实现您尝试执行的操作。一种方法是在您的应用程序中修改该记录。保存更改。

答案 1 :(得分:2)

您可以将collection.updateOne() upsert设置为true来重新编写记录。我们的想法是获取原始文档,在应用程序逻辑中修改它,然后在从数组中删除元素后将其重新应用到数据库中。

function upsert(collection, query, json) {
    var col = db.collection(collection);
    col.updateOne(query
        , { $set : json }
        , { upsert : true }
        , function (err, result) {
            if(err) {
                log('error = ', err);
            } else {
                // no error, call the next function
            }
        }
    );
};

答案 2 :(得分:1)

按照设计,mongodb的$pull运算符从现有数组中删除与指定条件匹配的值的所有实例。因此,它将从数组中删除所有匹配的{"name":"the alchemist"}元素

我想我会使用$pop,它只删除第一个匹配的元素。

db.collection("colName")
    .update({"owner": "princu7"}
            , {$pop: {"books": {$match: {"name": "the alchemist"}}}}
            , {multi:false}
)