从MongoDB中的数组中删除多个文档

从MongoDB中的数组中删除多个文档,mongodb,Mongodb,我的文档包含如下数组: { “差异诊断”:“IART/颤振”, “解释”:“节奏”, “文件名”:“A115a JPEG.jpg”, 《历史》:“一岁多愁善感”, “解释列表”:[ { “解释”:[ ObjectId(“54efe7c8d6d5ca3d5c580a22”), 目标(“54efe80bd6d5ca3d5c580a26”) ] }, { “解释”:[ 目标(“54efe80bd6d5ca3d5c580a26”), ObjectId(“54efe82ad6d5ca3d5c580a28

我的文档包含如下数组:

{
“差异诊断”:“IART/颤振”,
“解释”:“节奏”,
“文件名”:“A115a JPEG.jpg”,
《历史》:“一岁多愁善感”,
“解释列表”:[
{
“解释”:[
ObjectId(“54efe7c8d6d5ca3d5c580a22”),
目标(“54efe80bd6d5ca3d5c580a26”)
]
}, 
{
“解释”:[
目标(“54efe80bd6d5ca3d5c580a26”),
ObjectId(“54efe82ad6d5ca3d5c580a28”)
]
}
],
}
我想删除所有出现的
ObjectId(“54efe80bd6d5ca3d5c580a26”)
, 但我写了一个问题:

db.ekgs.update({'interpremissionlist.intermissions':ObjectId(“54c09fb3581c4c8c218d1a40”),{$pull:{'intermissionlist.$.intermissions':{ObjectId(“54c09fb3581c8c218d1a40”)})

只删除
ObjectId(“54efe80bd6d5ca3d5c580a26”)
的第一个匹配项查询只删除第一个匹配项的原因是,如文档中所述,“位置
$
运算符充当与查询文档匹配的第一个元素的占位符”

问题是,使用在嵌入数组中的嵌入对象中具有嵌入数组的架构来处理这些类型的更新非常棘手。为了避免此问题,如果您能够展平架构,则更新将变得更加容易。因此,如果相反,您的文档如下所示:

{
“差异诊断”:“IART/颤振”,
“解释”:“节奏”,
“文件名”:“A115a JPEG.jpg”,
《历史》:“一岁多愁善感”,
“解释”:[
ObjectId(“54efe7c8d6d5ca3d5c580a22”),
目标(“54efe80bd6d5ca3d5c580a26”),
ObjectId(“54efe82ad6d5ca3d5c580a28”)
]
}
然后,您的查询将与下面的查询一样简单。(如果要更新多个文档,请记住添加
{“multi”:true}
作为一个选项)

db.ekgs.update(
{“解释”:ObjectId(“54efe80bd6d5ca3d5c580a26”),
{“$pull”:{“解释”:ObjectId(“54efe80bd6d5ca3d5c580a26”)}
);
但是我知道您可能无法更改模式。在这种情况下,您可以尝试一种需要一个小脚本的解决方案。在
mongo
shell中,您可以使用以下JavaScript代码来执行操作

//获取需要更新的文档的游标。
变量oid=对象ID(“54efe80bd6d5ca3d5c580a26”);
var c=db.ekgs.find({“解释列表.解释”:oid});
//遍历游标,从解释列表中的每个子文档中删除oid。
while(c.hasNext()){
var isModified=假;
var doc=c.next();
var il=文件解释列表;
用于(il中的var i){
var j=il[i].解释.length;
而(j--){
//如果存在要删除的oid,请将其从阵列中删除
//并设置文档已修改的标志。
if(il[i][j].str===oid.str){
il[i].解释.剪接(j,1);
isModified=true;
}
}
}
//如果修改,更新文档的解释列表。
如果(已修改){
update({“\u id”:doc.\u id},{“$set”:{“解释列表”:il});
}
}
更新:使用Node.js驱动程序的示例

//获取需要更新的文档的游标。
var oid=新对象ID(“54efe80bd6d5ca3d5c580a26”);
var ekgs=数据库集合(“ekgs”);
ekgs.find({“解释列表.解释”:oid},
函数(err,c){
如果(错误)抛出错误;
//遍历游标,从解释列表中的每个子文档中删除oid。
c、 每个(功能(错误、文档){
如果(错误)抛出错误;
//如果单据为空,则光标耗尽/为空并关闭。
如果(doc!=null){
var isModified=假;
var il=文件解释列表;
用于(il中的var i){
var j=il[i].解释.length;
而(j--){
//如果存在要删除的oid,请将其从阵列中删除
//并设置文档已修改的标志。
如果(il[i]
il[i].解释.剪接(j,1);
isModified=true;
}
}
}           
//如果修改,更新文档的解释列表。
如果(已修改){
更新({“\u id”:doc.\u id},
{“$set”:{“解释列表”:il},
函数(err、res){
如果(错误)抛出错误;
//回拨。
控制台日志(res);
});
}
}
});
});

这不是在MongoDB或JSON或BSON下可能出现的有效文档结构。在这种模式下可能出现这种情况吗?如果是,您可以建议吗?这源自基本的JSON符号。“解释”之后不可能是没有“键”的子文档姓名。如果你想问一个问题,那么我们至少要求你问一些有效的问题。对不起,这是一个错误,我更正了。如果任何人有任何建议,请帮助。我在过去两天一直在处理这个问题。它好吗?我想这会影响我们的服务响应时间。它在mongo shell中不起作用。它是通过错误实现的。c是未定义的。我如何才能确定我明白了。问题是,在
mongo
shell中,您可以将
db.collection.find()
的返回值分配给一个变量。因此,行:
var c=db.ekgs.find({“interprelationlist.interprelations”):oid})