这就是我的收藏的样子:
db.students.find({_id:100}).pretty()
{
"_id" : 100,
"name" : "Demarcus Audette",
"scores" : [
{
"type" : "exam",
"score" : 30.61740640636871
},
{
"type" : "quiz",
"score" : 14.23233821353732
},
{
"type" : "homework",
"score" : 31.41421298576332
},
{
"type" : "homework",
"score" : 30.09304792394713
}
]
}
Run Code Online (Sandbox Code Playgroud)
我正在 Mongo shell 上执行以下 2 个查询:
x=db.students.aggregate( [{ "$unwind":"$scores" },{"$match":{"scores.type":"homework"}},{ "$group":{"_id":"$_id","minscore":{"$min":"$scores.score" }}} ] )
Run Code Online (Sandbox Code Playgroud)
下一个是:
for (var a in x["a"]) { db.students.update( { "_id":a["_id"] },{"$pull":{"scores":{"score":a["minscore"]}}} ) }
Run Code Online (Sandbox Code Playgroud)
我可以看到最低分数列表,但是当我执行第二个查询时,似乎没有任何内容被删除。我知道有逻辑错误。我试图阅读这里的帖子,但我无法通过它。我只是想知道我哪里出了问题。
你的 for 循环中有几个问题 - 尽管你的聚合看起来不错。
您的结果文档“x”包含一个数组字段“result”。您想要迭代该数组中的文档。for 循环语法不会将 a 设置为数组中的值,而是设置为数组中的索引。更好、更清晰的是使用 forEach 循环语法:
x.result.forEach(function(doc) {
db.students.update( { "_id": doc._id },
{ "$pull": { "scores" : {
"score":doc.minscore,
"type":"homework"
} } }
);
});
Run Code Online (Sandbox Code Playgroud)
您的更新声明也不太准确 - 您想确保只提取分数最低的作业- 如果同一个学生的一次考试分数也与最低分数相同怎么办?您的语法将提取分数等于 minscore 的所有子文档!
这个问题很容易修复(我向您展示了仅提取作业子文档所需的语法),但请记住$pull 将提取与查询匹配的所有值,如果只有一项作业,则它是最低分数和它会被拉动。如果有两个作业成绩相同,那么他们都会被拉掉!需要考虑的事情。