(lehu6.vip官网直营平台) mongodb高级修改问题

描述: 格式如下所示,其中每个对象有_id,name,和一个数组scores,其中可以看到修改前的数组中,每个document有两个type为”homework”的对象。
*提问*: 问题是如何操纵mongo数据库,批量修改db.students,让每个document中,删除score较小的homework,而保留score较大的homework。

修改前:

{ "_id" : 100, "name" : "Demarcus Audette", "scores" : [ { "score" : 47.42608580155614, "type" : "exam" }, { "score" : 44.83416623719906, "type" : "quiz" }, { "score" : 19.01726616178844, "type" : "homework" }, { "score" : 39.01726616178844, "type" : "homework" } ]
} 

修改后:

{ "_id" : 100, "name" : "Demarcus Audette", "scores" : [ { "score" : 47.42608580155614, "type" : "exam" }, { "score" : 44.83416623719906, "type" : "quiz" }, { "score" : 39.01726616178844, "type" : "homework" } ]
} 

下面附上一段nodejs上跑的代码(自己写的,有问题跑不通,作为参考):

var MongoClient = requiremongodb.MongoClient;
MongoClient.connectmongodb://localhost:27017/school, functionerr, db{ iferr throw err; var query = {}; var cursor = db.collectionstudents.findquery; cursor.eachfunctionerr, doc{ iferrthrow err; ifdoc == null{return db.close;} /*TODO*/ var target1 = doc.scores[2]; var target2 = doc.scores[3]; iftarget1 < target2 doc.update{$unset: target1}; else doc.update{$unset: target2}; console.dir"Successfully found " + target1; };
};

var MongoClient = requiremongodb.MongoClient; MongoClient.connectmongodb://school:school@localhost:27017/school, functionerr, db { if err { throw err; } var student = db.collectionstudents; var updateData = functionnewdoc { //把旧的删除 student.findAndRemove{_id: newdoc._id}, functionerr, olddoc { if err { throw err; } olddoc && console.logremove olddoc id: %s, olddoc._id; //插入新的 student.insertnewdoc, functionerr, saveResult { if err { throw err; } saveResult && console.log[OK] update ok , id: %s, newdoc._id; saveResult || console.log[ERR] update fail, id: %s, newdoc._id; }; }; }; //插入测试数据 student.insert[ { name: hehehe, scores: [ { score: 97.42608580155614, type: exam, }, { score: 14.83416623719906, type: quiz, }, { score: 55.01726616178844, type: homework, }, { score: 3.0172661617884, type: homework, } ], }, { name: Demarcus Audette, scores: [ { score: 47.42608580155614, type: exam, }, { score: 44.83416623719906, type: quiz, }, { score: 19.01726616178844, type: homework, }, { score: 39.0172661617884, type: homework, } ], }, ], functionerr, result { if err { throw err; } //聚合 student.aggregate[ {$unwind: $scores}, {$group: { _id: { _id: $_id, name: $name, type: $scores.type, }, score: { $max: $scores.score } }}, {$project: { _id: { _id: $_id._id, name: $_id.name, }, scores: { type: $_id.type, score: $score, }, }}, {$group: { _id: $_id, scores: { $push: $scores, } }} ], functionerr, result { if err { throw err; } //循环结果 result.forEachfunctionitem { item = { _id: item._id._id, name: item._id.name, score: item.scores }; updateDataitem; }; }; }; };

我估计你想要的是 in place update,比如 findAndEval 类似的方法,然后要让你失望了

https://jira.mongodb.org/browse/SERVER-458

目前为止还没有实现,被列在 Planning Bucket B 里,实现目测遥遥无期。


嗯,上面说的没有实现是指没法在服务器端完成(mongo 和 mongod 的关系)

如果在客户端完成,可以用 cursor.forEach 方法,比如

db.students.find.snapshot.forEach function e { e.删除score较小的homework!; db.students.savee; } 

发表评论

电子邮件地址不会被公开。 必填项已用*标注