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 = 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);
    });
});

node.js json nosql mongodb

银河美嬷嬷 10 years, 6 months ago

 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);
      });
    });    

  });


});

树荫里的大象 answered 10 years, 6 months ago

Your Answer