首页 > 开发 > NodeJS > 正文

mongodb高级修改问题

2017-09-08 17:34:10  来源:网友分享

描述: 格式如下所示,其中每个对象有_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 = require('mongodb').MongoClient;MongoClient.connect('mongodb://localhost:27017/school', function(err, db){    if(err) throw err;    var query = {};    var cursor = db.collection('students').find(query);    cursor.each(function(err, doc){        if(err)throw err;        if(doc == null){return db.close();}        /*TODO*/        var target1 = doc.scores[2];        var target2 = doc.scores[3];        if(target1 < target2) doc.update({$unset: target1});            else doc.update({$unset: target2});        console.dir("Successfully found " + target1);    });});

解决方案

var MongoClient = require('mongodb').MongoClient;MongoClient.connect('mongodb://school:school@localhost:27017/school', function(err, db) {  if (err) {    throw err;  }  var student = db.collection('students');  var updateData = function(newdoc) {    //把旧的删除    student.findAndRemove({_id: newdoc._id}, function(err, olddoc) {      if (err) {        throw err;      }      olddoc && console.log('remove olddoc id: %s', olddoc._id);      //插入新的      student.insert(newdoc, function(err, 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',        }      ],    },  ], function(err, 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',        }      }}    ], function(err, result) {      if (err) {        throw err;      }      //循环结果      result.forEach(function(item) {        item = {          _id: item._id._id,          name: item._id.name,          score: item.scores        };        updateData(item);      });    });      });});