我有一个问题,我正在努力相当一段时间。假装我的文件是这样的
{"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会删除所有匹配所需条件的实例,这也许就是为什么它会删除匹配条件的数组的所有其他条目。所以我该怎么做。谢谢阅读。感谢你的帮助。
答案 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}
)