这是我的收藏品的样子:
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
}
]
}
我在Mongo shell上执行以下2个查询:
x=db.students.aggregate( [{ "$unwind":"$scores" },{"$match":{"scores.type":"homework"}},{ "$group":{"_id":"$_id","minscore":{"$min":"$scores.score" }}} ] )
,下一个是:
for (var a in x["a"]) { db.students.update( { "_id":a["_id"] },{"$pull":{"scores":{"score":a["minscore"]}}} ) }
我能够看到最低分数列表,但是当我执行第二个查询时似乎没有删除任何内容。我知道有一个逻辑错误。我试着阅读这里的帖子,但我无法通过它。我只是想知道我哪里出错了。
答案 0 :(得分:4)
你的for循环中有几个问题 - 虽然你的聚合看起来不错。
您的结果文档“x”包含数组字段“result”。您想迭代该数组中的文档。您拥有的for循环语法不会在数组中设置值,而是在数组中设置索引。更好更清楚的是使用forEach循环语法:
x.result.forEach(function(doc) {
db.students.update( { "_id": doc._id },
{ "$pull": { "scores" : {
"score":doc.minscore,
"type":"homework"
} } }
);
});
您的更新声明也不太准确 - 您希望确保只拉出分数最低的作业 - 如果同一个学生的单个考试成绩相同,该怎么办?作为他们最低的功课?您的语法将拉出所有分数等于minscore的子文档!
那个很容易修复(并且我向您展示了仅用于提取家庭作业子文档的语法),但请记住与查询匹配的$pull will pull all values,如果只有一个作业,那么它就是minscore,它会被拉。如果有两个家庭作业但他们是平等的,他们会两个被拉!需要考虑的事情。
答案 1 :(得分:2)
使用以下代码删除最低分数。聚合代码没问题。
x=db.students.aggregate( [{ "$unwind":"$scores" },{"$match":{"scores.type":"homework"}},{ "$group":{"_id":"$_id","minscore":{"$min":"$scores.score" }}} ] );
var doc = myCursor.hasNext() ? x.next() : null;
x.forEach(function(doc) {db.students.update( { "_id": doc._id }, { "$pull": { "scores" : {
"score":doc.minscore, "type":"homework"} } } );
在MongoShell上运行上面的代码后 - db.students.find.pretty(); 你会得到文件中的记录 -
{
"_id" : 100,
"name" : "Demarcus Audette",
"scores" : [
{
"type" : "exam",
"score" : 30.61740640636871
},
{
"type" : "quiz",
"score" : 14.23233821353732
},
{
"type" : "homework",
"score" : 31.41421298576332
},
]
}
类型的最低分:"家庭作业"将从每个记录集中删除。
答案 2 :(得分:0)
这是因为当你这样做时:
x = db.students.aggregate([
{ "$unwind":"$scores" },
{"$match":{
"scores.type":"homework"
}},
{
"$group":{
"_id":"$_id",
"minscore":{"$min":"$scores.score" }}
}
]);
您的结果采用以下形式:
{
result : [{
"_id" : 100,
"minscore" : 30.09304792394713
}],
ok : 1
}
所以那里没有x["a"]
,你需要写x['result']
。
P.S。如果你正在做作业问题,你应该写下来。
答案 3 :(得分:0)
根据其他答案的组合,以下是与我合作的答案。
x = db.students.aggregate([
{ "$unwind":"$scores" },
{"$match":{
"scores.type":"homework"
}},
{
"$group":{
"_id":"$_id",
"minscore":{"$min":"$scores.score" }}
}
]);
x.result.forEach(function(doc) {db.students.update( { "_id": doc._id }, { "$pull": { "scores" : {
"score":doc.minscore,"type":"homework" } } }); });
答案 4 :(得分:0)
以下代码为我工作。
var x=db.students.aggregate( [{ "$unwind":"$scores" },{"$match":{"scores.type":"homework"}},{"$group":{"_id":"$_id","minscore":{"$min":"$scores.score" }}} ] );
var doc = x.hasNext() ? x.next() : null;
x.forEach(function(doc){
db.students.update( { "_id": doc._id }, { "$pull": { "scores" : { "score":doc.minscore, "type":"homework"} } } );
});