如何在mongoDB中对集合记录中的数组进行排序

时间:2022-01-05 21:18:00

MongoDB noob here...

MongoDB新手在这里……

Ok, I have a collection of students, each with a record that looks like the following.... I want to sort the 'type' : 'homework' scores in descending order.

好的,我有一个学生的集合,每一个都有记录,看起来就像以下....我想按降序排列“类型”:“家庭作业”的分数。

what does that incantation look like on the mongo shell?

蒙高贝壳上的咒语是什么样子的?

> db.students.find({'_id': 1}).pretty()
{
        "_id" : 1,
        "name" : "Aurelia Menendez",
        "scores" : [
                {
                        "type" : "exam",
                        "score" : 60.06045071030959
                },
                {
                        "type" : "quiz",
                        "score" : 52.79790691903873
                },
                {
                        "type" : "homework",
                        "score" : 71.76133439165544
                },
                {
                        "type" : "homework",
                        "score" : 34.85718117893772
                }
        ]
}

I'm trying this incantation....

我在这咒语....

 doc = db.students.find()

 for (_id,score) in doc.scores:
     print _id,score

but it's not working.

但这不是工作。

13 个解决方案

#1


37  

You will need to manipulate the embedded array in your application code or using the new Aggregation Framework in MongoDB 2.2.

您将需要操作应用程序代码中的嵌入数组,或者使用MongoDB 2.2中的新聚合框架。

Example aggregation in the mongo shell:

mongo shell中的示例聚合:

db.students.aggregate(
    // Initial document match (uses index, if a suitable one is available)
    { $match: {
        _id : 1
    }},

    // Expand the scores array into a stream of documents
    { $unwind: '$scores' },

    // Filter to 'homework' scores 
    { $match: {
        'scores.type': 'homework'
    }},

    // Sort in descending order
    { $sort: {
        'scores.score': -1
    }}
)

Sample output:

样例输出:

{
    "result" : [
        {
            "_id" : 1,
            "name" : "Aurelia Menendez",
            "scores" : {
                "type" : "homework",
                "score" : 71.76133439165544
            }
        },
        {
            "_id" : 1,
            "name" : "Aurelia Menendez",
            "scores" : {
                "type" : "homework",
                "score" : 34.85718117893772
            }
        }
    ],
    "ok" : 1
}

#2


6  

That's how we could solve this with JS and mongo console:

这就是我们用JS和mongo控制台解决这个问题的方法:

db.students.find({"scores.type": "homework"}).forEach(
  function(s){
    var sortedScores = s.scores.sort(
      function(a, b){
        return a.score<b.score && a.type=="homework";
      }
    );
    var lowestHomeworkScore = sortedScores[sortedScores.length-1].score;
    db.students.update({_id: s._id},{$pull: {scores: {score: lowestHomeworkScore}}}, {multi: true});
  })

#3


3  

Here is the java code which can be used to find out the lowest score in the array and remove it.

下面是java代码,可用于查找数组中的最低值并删除它。

public class sortArrayInsideDocument{
public static void main(String[] args) throws UnknownHostException {
    MongoClient client = new MongoClient();
    DB db = client.getDB("school");
    DBCollection lines = db.getCollection("students");
    DBCursor cursor = lines.find();
    try {
        while (cursor.hasNext()) {
            DBObject cur = cursor.next();
            BasicDBList dbObjectList = (BasicDBList) cur.get("scores");
            Double lowestScore = new Double(0);
            BasicDBObject dbObject = null;
            for (Object doc : dbObjectList) {
                BasicDBObject basicDBObject = (BasicDBObject) doc;
                if (basicDBObject.get("type").equals("homework")) {
                    Double latestScore = (Double) basicDBObject
                            .get("score");
                    if (lowestScore.compareTo(Double.valueOf(0)) == 0) {
                        lowestScore = latestScore;
                        dbObject = basicDBObject;

                    } else if (lowestScore.compareTo(latestScore) > 0) {
                        lowestScore = latestScore;
                        dbObject = basicDBObject;
                    }
                }
            }
            // remove the lowest score here.
            System.out.println("object to be removed : " + dbObject + ":"
                    + dbObjectList.remove(dbObject));
            // update the collection
            lines.update(new BasicDBObject("_id", cur.get("_id")), cur,
                    true, false);
        }
    } finally {
        cursor.close();
    }
}
}

#4


2  

It's easy enough to guess, but anyway, try not cheat with mongo university courses because you won't understand basics then.

这很容易猜到,但是无论如何,试着不要欺骗mongo大学的课程,因为你根本就不懂基础知识。

db.students.find({}).forEach(function(student){ 

    var minHomeworkScore,  
        scoresObjects = student.scores,
        homeworkArray = scoresObjects.map(
            function(obj){
                return obj.score;
            }
        ); 

    minHomeworkScore = Math.min.apply(Math, homeworkArray);

    scoresObjects.forEach(function(scoreObject){ 
        if(scoreObject.score === minHomeworkScore){ 
            scoresObjects.splice(scoresObjects.indexOf(minHomeworkScore), 1); 
        } 
    });

    printjson(scoresObjects);

});

#5


1  

Since this question can be managed in different ways i want to say that another solution is "insert and sort", in this way you will get the Ordered array at the moment you will made a Find().

由于这个问题可以以不同的方式进行管理,所以我想说另一个解决方案是“插入和排序”,这样您将在创建Find()时获得有序数组。

Consider this data:

考虑一下这个数据:

{
   "_id" : 5,
   "quizzes" : [
      { "wk": 1, "score" : 10 },
      { "wk": 2, "score" : 8 },
      { "wk": 3, "score" : 5 },
      { "wk": 4, "score" : 6 }
   ]
}

Here we will update the Document, make the Sort.

这里我们将更新文档,进行排序。

db.students.update(
   { _id: 5 },
   {
     $push: {
       quizzes: {
          $each: [ { wk: 5, score: 8 }, { wk: 6, score: 7 }, { wk: 7, score: 6 } ],
          $sort: { score: -1 },
          $slice: 3 // keep the first 3 values
       }
     }
   }
)

Result is:

结果是:

{
  "_id" : 5,
  "quizzes" : [
     { "wk" : 1, "score" : 10 },
     { "wk" : 2, "score" : 8 },
     { "wk" : 5, "score" : 8 }
  ]
}

Documentation: https://docs.mongodb.com/manual/reference/operator/update/sort/#up._S_sort

文档:https://docs.mongodb.com/manual/reference/operator/update/sort/ up._S_sort

#6


0  

the answer of @Stennie is fine, maybe a $group operator would be useful to keep the original document, without exploding it in many documents (one by score).

@Stennie的答案是好的,也许$group操作符对于保存原始文档很有用,而不会在许多文档中(一个一个一个地)爆炸它。

I just add another solution when using javascript for your application.

我只是在使用javascript时添加了另一个解决方案。

if you query only one document, it's sometimes easier to sort the embedded array by JS, instead of doing an aggregate. When your document has a lot of fields, it's even better than using $push operator, otherwise you've to push all the fields one by one, or use $$ROOT operator (am I wrong ?)

如果只查询一个文档,那么使用JS对嵌入的数组进行排序比使用聚合要容易得多。当您的文档有很多字段时,它甚至比使用$push操作符更好,否则您必须一个一个地推动所有字段,或者使用$ROOT操作符(我错了吗?)

My example code uses Mongoose.js : Suppose you have initialized you Students model.

我的示例代码使用Mongoose。假设你已经初始化了你的学生模型。

// Sorting
function compare(a, b) {
  return a.score - b.score;
}

Students.findById('1', function(err, foundDocument){
  foundDocument.scores = foundDocument.scores.sort(compare);

  // do what you want here...
  // foundModel keeps all its fields
});

#7


0  

this work for me, it is a little rough code but the results of the lowest tasks for each student are correct.

对于我来说,这是一个粗略的代码,但是每个学生的最低任务的结果是正确的。

var scores_homework = []
db.students.find({"scores.type": "homework"}).forEach(
  function(s){
    s.scores.forEach(
        function(ss){
            if(ss.type=="homework"){
                ss.student_id = s._id
                scores_homework.push(ss)
            }
        }
    )
})
for(i = 0; i < scores_homework.length; i++)
{
    var b = i+1;
    var ss1 = scores_homework[i];
    var ss2 = scores_homework[b];
    var lowest_score = {};
    if(ss1.score > ss2.score){
        lowest_score.type = ss2.type;
        lowest_score.score = ss2.score;
        db.students.update({_id: ss2.student_id},{$pull: {scores: {score: lowest_score.score}}});
    }else if(ss1.score < ss2.score){
        lowest_score.type = ss1.type;
        lowest_score.score = ss1.score;
        db.students.update({_id: ss1.student_id},{$pull: {scores: {score: lowest_score.score}}});
    }else{
        lowest_score.type = ss1.type;
        lowest_score.score = ss1.score;
        db.students.update({_id: ss1.student_id},{$pull: {scores: {score: lowest_score.score}}});
    }
    i++
}

#8


0  

I believe you are doing M101P: MongoDB for Developers where homework 3.1 is to remove the lower one from two homework scores. Since aggregations were not taught up to that point you can do something like this:

我相信你正在做M101P: MongoDB为开发人员做作业3.1,从两个作业的分数中删除较低的一个。因为聚合没有被教授到那个点你可以做这样的事情:

import pymongo

conn = pymongo.MongoClient('mongodb://localhost:27017')
db = conn.school
students = db.students

for student_data in students.find():
    smaller_homework_score_seq = None
    smaller_homework_score_val = None
    for score_seq, score_data in enumerate(student_data['scores']):
        if score_data['type'] == 'homework':
            if smaller_homework_score_seq is None or smaller_homework_score_val > score_data['score']:
                smaller_homework_score_seq = score_seq
                smaller_homework_score_val = score_data['score']
    students.update({'_id': student_data['_id']}, {'$pop': {'scores': smaller_homework_score_seq}})

#9


0  

This is my approach using pyMongo, the Python driver to MongoDB:

这是我使用pyMongo的方法,pyMongo是MongoDB的Python驱动程序:

import pymongo


conn = pymongo.MongoClient('mongodb://localhost')

def remove_lowest_hw():
    db = conn.school
    students = db.students

    # first sort scores in ascending order
    students.update_many({}, {'$push':{'scores':{'$each':[], '$sort':{'score': 1}}}})

    # then collect the lowest homework score for each student via projection
    cursor = students.find({}, {'scores':{'$elemMatch':{'type':'homework'}}})

    # iterate over each student, trimming each of the lowest homework score
    for stu in cursor:
        students.update({'_id':stu['_id']}, {'$pull':{'scores':{'score':stu['scores'][0]['score']}}})

remove_lowest_hw()

conn.close()

#10


0  

This is how I have implemented in Java (Have kept it simple so that it's easier to understand) -

这就是我如何在Java中实现的(保持它的简单,以便更容易理解)-

Approach :

方法:

  1. Get scores array from student collection
  2. 从学生集合中获取分数数组
  3. Get all score values from scores array where type == homework
  4. 从score数组中获取所有分数值,其中type = homework
  5. Sort the score values so that lowest becomes 1st element [score.get(0)]
  6. 对得分值进行排序,使最低值成为第一个元素[计分。获取(0)]
  7. Then, loop through the main scores and create new copy of scores array while skipping elements where type == homework && score == scores.get(0)
  8. 然后,循环遍历主分数并创建新的分数数组副本,同时跳过type =家庭作业&& score = score .get(0)的元素
  9. Finally, update the new scores array to student document.
  10. 最后,将新的分数数组更新为学生文档。

Below is working Java code:

下面是工作Java代码:

    public void removeLowestScore(){
    //Create mongo client and database connection and get collection
    MongoClient client = new MongoClient("localhost");
    MongoDatabase database = client.getDatabase("school");
    MongoCollection<Document> collection = database.getCollection("students");


    FindIterable<Document> docs = collection.find();
    for (Document document : docs) {

        //Get scores array
        ArrayList<Document> scores = document.get("scores", ArrayList.class);           

        //Create a list of scores where type = homework
        List<Double> homeworkScores = new ArrayList<Double>();
        for (Document score : scores) {
            if(score.getString("type").equalsIgnoreCase("homework")){
                homeworkScores.add(score.getDouble("score"));   
            }
        }

        //sort homework scores
        Collections.sort(homeworkScores);

        //Create a new list to update into student collection
        List<Document> newScoresArray = new ArrayList<Document>();
        Document scoreDoc = null;

        //Below loop populates new score array with eliminating lowest score of "type" = "homework"
        for (Document score : scores) {
            if(score.getString("type").equalsIgnoreCase("homework") && homeworkScores.get(0) == score.getDouble("score")){                  
                    continue;                       
                }else{
                    scoreDoc = new Document("type",score.getString("type"));
                    scoreDoc.append("score",score.getDouble("score"));
                    newScoresArray.add(scoreDoc);
                }               
            }           

        //Update the scores array for every student using student _id
        collection.updateOne(Filters.eq("_id", document.getInteger("_id")), new Document("$set",new Document("scores",newScoresArray)));
    }       
}

#11


0  

Certainly it's late, but I just want to contribute my own solution on Mongo Shell:

当然已经很晚了,但我只想对Mongo Shell提供我自己的解决方案:

var students = db.getCollection('students').find({});
for(i = 0 ; i < students.length(); i++) {
    var scores = students[i].scores;
    var tmp = [];
    var min = -1 ;
    var valueTmp = {};
    for(j = 0 ; j < scores.length; j++) {        
        if(scores[j].type != 'homework') {
            tmp.push(scores[j]);
        } else {
            if (min == -1) {
                min = scores[j].score;
                valueTmp = scores[j];
            } else {
                if (min > scores[j].score) {
                    min = scores[j].score;
                    tmp.push(valueTmp);
                    valueTmp = scores[j];
                } else {
                    tmp.push(scores[j]);
                }
            }
        }
    }
    db.students.updateOne({_id:students[i]._id},
                            {$set:{scores:tmp}});
}

#12


-1  

sort by the score can be simple like:

按分数排序可以很简单:

db.students.find({_id:137}).sort({score:-1}).pretty()

but you need to find the one for type:homework ...

但是你需要找到一个类型:家庭作业……

#13


-2  

it should be something like this:

应该是这样的:

db.students.find().sort(scores: ({"score":-1}));

#1


37  

You will need to manipulate the embedded array in your application code or using the new Aggregation Framework in MongoDB 2.2.

您将需要操作应用程序代码中的嵌入数组,或者使用MongoDB 2.2中的新聚合框架。

Example aggregation in the mongo shell:

mongo shell中的示例聚合:

db.students.aggregate(
    // Initial document match (uses index, if a suitable one is available)
    { $match: {
        _id : 1
    }},

    // Expand the scores array into a stream of documents
    { $unwind: '$scores' },

    // Filter to 'homework' scores 
    { $match: {
        'scores.type': 'homework'
    }},

    // Sort in descending order
    { $sort: {
        'scores.score': -1
    }}
)

Sample output:

样例输出:

{
    "result" : [
        {
            "_id" : 1,
            "name" : "Aurelia Menendez",
            "scores" : {
                "type" : "homework",
                "score" : 71.76133439165544
            }
        },
        {
            "_id" : 1,
            "name" : "Aurelia Menendez",
            "scores" : {
                "type" : "homework",
                "score" : 34.85718117893772
            }
        }
    ],
    "ok" : 1
}

#2


6  

That's how we could solve this with JS and mongo console:

这就是我们用JS和mongo控制台解决这个问题的方法:

db.students.find({"scores.type": "homework"}).forEach(
  function(s){
    var sortedScores = s.scores.sort(
      function(a, b){
        return a.score<b.score && a.type=="homework";
      }
    );
    var lowestHomeworkScore = sortedScores[sortedScores.length-1].score;
    db.students.update({_id: s._id},{$pull: {scores: {score: lowestHomeworkScore}}}, {multi: true});
  })

#3


3  

Here is the java code which can be used to find out the lowest score in the array and remove it.

下面是java代码,可用于查找数组中的最低值并删除它。

public class sortArrayInsideDocument{
public static void main(String[] args) throws UnknownHostException {
    MongoClient client = new MongoClient();
    DB db = client.getDB("school");
    DBCollection lines = db.getCollection("students");
    DBCursor cursor = lines.find();
    try {
        while (cursor.hasNext()) {
            DBObject cur = cursor.next();
            BasicDBList dbObjectList = (BasicDBList) cur.get("scores");
            Double lowestScore = new Double(0);
            BasicDBObject dbObject = null;
            for (Object doc : dbObjectList) {
                BasicDBObject basicDBObject = (BasicDBObject) doc;
                if (basicDBObject.get("type").equals("homework")) {
                    Double latestScore = (Double) basicDBObject
                            .get("score");
                    if (lowestScore.compareTo(Double.valueOf(0)) == 0) {
                        lowestScore = latestScore;
                        dbObject = basicDBObject;

                    } else if (lowestScore.compareTo(latestScore) > 0) {
                        lowestScore = latestScore;
                        dbObject = basicDBObject;
                    }
                }
            }
            // remove the lowest score here.
            System.out.println("object to be removed : " + dbObject + ":"
                    + dbObjectList.remove(dbObject));
            // update the collection
            lines.update(new BasicDBObject("_id", cur.get("_id")), cur,
                    true, false);
        }
    } finally {
        cursor.close();
    }
}
}

#4


2  

It's easy enough to guess, but anyway, try not cheat with mongo university courses because you won't understand basics then.

这很容易猜到,但是无论如何,试着不要欺骗mongo大学的课程,因为你根本就不懂基础知识。

db.students.find({}).forEach(function(student){ 

    var minHomeworkScore,  
        scoresObjects = student.scores,
        homeworkArray = scoresObjects.map(
            function(obj){
                return obj.score;
            }
        ); 

    minHomeworkScore = Math.min.apply(Math, homeworkArray);

    scoresObjects.forEach(function(scoreObject){ 
        if(scoreObject.score === minHomeworkScore){ 
            scoresObjects.splice(scoresObjects.indexOf(minHomeworkScore), 1); 
        } 
    });

    printjson(scoresObjects);

});

#5


1  

Since this question can be managed in different ways i want to say that another solution is "insert and sort", in this way you will get the Ordered array at the moment you will made a Find().

由于这个问题可以以不同的方式进行管理,所以我想说另一个解决方案是“插入和排序”,这样您将在创建Find()时获得有序数组。

Consider this data:

考虑一下这个数据:

{
   "_id" : 5,
   "quizzes" : [
      { "wk": 1, "score" : 10 },
      { "wk": 2, "score" : 8 },
      { "wk": 3, "score" : 5 },
      { "wk": 4, "score" : 6 }
   ]
}

Here we will update the Document, make the Sort.

这里我们将更新文档,进行排序。

db.students.update(
   { _id: 5 },
   {
     $push: {
       quizzes: {
          $each: [ { wk: 5, score: 8 }, { wk: 6, score: 7 }, { wk: 7, score: 6 } ],
          $sort: { score: -1 },
          $slice: 3 // keep the first 3 values
       }
     }
   }
)

Result is:

结果是:

{
  "_id" : 5,
  "quizzes" : [
     { "wk" : 1, "score" : 10 },
     { "wk" : 2, "score" : 8 },
     { "wk" : 5, "score" : 8 }
  ]
}

Documentation: https://docs.mongodb.com/manual/reference/operator/update/sort/#up._S_sort

文档:https://docs.mongodb.com/manual/reference/operator/update/sort/ up._S_sort

#6


0  

the answer of @Stennie is fine, maybe a $group operator would be useful to keep the original document, without exploding it in many documents (one by score).

@Stennie的答案是好的,也许$group操作符对于保存原始文档很有用,而不会在许多文档中(一个一个一个地)爆炸它。

I just add another solution when using javascript for your application.

我只是在使用javascript时添加了另一个解决方案。

if you query only one document, it's sometimes easier to sort the embedded array by JS, instead of doing an aggregate. When your document has a lot of fields, it's even better than using $push operator, otherwise you've to push all the fields one by one, or use $$ROOT operator (am I wrong ?)

如果只查询一个文档,那么使用JS对嵌入的数组进行排序比使用聚合要容易得多。当您的文档有很多字段时,它甚至比使用$push操作符更好,否则您必须一个一个地推动所有字段,或者使用$ROOT操作符(我错了吗?)

My example code uses Mongoose.js : Suppose you have initialized you Students model.

我的示例代码使用Mongoose。假设你已经初始化了你的学生模型。

// Sorting
function compare(a, b) {
  return a.score - b.score;
}

Students.findById('1', function(err, foundDocument){
  foundDocument.scores = foundDocument.scores.sort(compare);

  // do what you want here...
  // foundModel keeps all its fields
});

#7


0  

this work for me, it is a little rough code but the results of the lowest tasks for each student are correct.

对于我来说,这是一个粗略的代码,但是每个学生的最低任务的结果是正确的。

var scores_homework = []
db.students.find({"scores.type": "homework"}).forEach(
  function(s){
    s.scores.forEach(
        function(ss){
            if(ss.type=="homework"){
                ss.student_id = s._id
                scores_homework.push(ss)
            }
        }
    )
})
for(i = 0; i < scores_homework.length; i++)
{
    var b = i+1;
    var ss1 = scores_homework[i];
    var ss2 = scores_homework[b];
    var lowest_score = {};
    if(ss1.score > ss2.score){
        lowest_score.type = ss2.type;
        lowest_score.score = ss2.score;
        db.students.update({_id: ss2.student_id},{$pull: {scores: {score: lowest_score.score}}});
    }else if(ss1.score < ss2.score){
        lowest_score.type = ss1.type;
        lowest_score.score = ss1.score;
        db.students.update({_id: ss1.student_id},{$pull: {scores: {score: lowest_score.score}}});
    }else{
        lowest_score.type = ss1.type;
        lowest_score.score = ss1.score;
        db.students.update({_id: ss1.student_id},{$pull: {scores: {score: lowest_score.score}}});
    }
    i++
}

#8


0  

I believe you are doing M101P: MongoDB for Developers where homework 3.1 is to remove the lower one from two homework scores. Since aggregations were not taught up to that point you can do something like this:

我相信你正在做M101P: MongoDB为开发人员做作业3.1,从两个作业的分数中删除较低的一个。因为聚合没有被教授到那个点你可以做这样的事情:

import pymongo

conn = pymongo.MongoClient('mongodb://localhost:27017')
db = conn.school
students = db.students

for student_data in students.find():
    smaller_homework_score_seq = None
    smaller_homework_score_val = None
    for score_seq, score_data in enumerate(student_data['scores']):
        if score_data['type'] == 'homework':
            if smaller_homework_score_seq is None or smaller_homework_score_val > score_data['score']:
                smaller_homework_score_seq = score_seq
                smaller_homework_score_val = score_data['score']
    students.update({'_id': student_data['_id']}, {'$pop': {'scores': smaller_homework_score_seq}})

#9


0  

This is my approach using pyMongo, the Python driver to MongoDB:

这是我使用pyMongo的方法,pyMongo是MongoDB的Python驱动程序:

import pymongo


conn = pymongo.MongoClient('mongodb://localhost')

def remove_lowest_hw():
    db = conn.school
    students = db.students

    # first sort scores in ascending order
    students.update_many({}, {'$push':{'scores':{'$each':[], '$sort':{'score': 1}}}})

    # then collect the lowest homework score for each student via projection
    cursor = students.find({}, {'scores':{'$elemMatch':{'type':'homework'}}})

    # iterate over each student, trimming each of the lowest homework score
    for stu in cursor:
        students.update({'_id':stu['_id']}, {'$pull':{'scores':{'score':stu['scores'][0]['score']}}})

remove_lowest_hw()

conn.close()

#10


0  

This is how I have implemented in Java (Have kept it simple so that it's easier to understand) -

这就是我如何在Java中实现的(保持它的简单,以便更容易理解)-

Approach :

方法:

  1. Get scores array from student collection
  2. 从学生集合中获取分数数组
  3. Get all score values from scores array where type == homework
  4. 从score数组中获取所有分数值,其中type = homework
  5. Sort the score values so that lowest becomes 1st element [score.get(0)]
  6. 对得分值进行排序,使最低值成为第一个元素[计分。获取(0)]
  7. Then, loop through the main scores and create new copy of scores array while skipping elements where type == homework && score == scores.get(0)
  8. 然后,循环遍历主分数并创建新的分数数组副本,同时跳过type =家庭作业&& score = score .get(0)的元素
  9. Finally, update the new scores array to student document.
  10. 最后,将新的分数数组更新为学生文档。

Below is working Java code:

下面是工作Java代码:

    public void removeLowestScore(){
    //Create mongo client and database connection and get collection
    MongoClient client = new MongoClient("localhost");
    MongoDatabase database = client.getDatabase("school");
    MongoCollection<Document> collection = database.getCollection("students");


    FindIterable<Document> docs = collection.find();
    for (Document document : docs) {

        //Get scores array
        ArrayList<Document> scores = document.get("scores", ArrayList.class);           

        //Create a list of scores where type = homework
        List<Double> homeworkScores = new ArrayList<Double>();
        for (Document score : scores) {
            if(score.getString("type").equalsIgnoreCase("homework")){
                homeworkScores.add(score.getDouble("score"));   
            }
        }

        //sort homework scores
        Collections.sort(homeworkScores);

        //Create a new list to update into student collection
        List<Document> newScoresArray = new ArrayList<Document>();
        Document scoreDoc = null;

        //Below loop populates new score array with eliminating lowest score of "type" = "homework"
        for (Document score : scores) {
            if(score.getString("type").equalsIgnoreCase("homework") && homeworkScores.get(0) == score.getDouble("score")){                  
                    continue;                       
                }else{
                    scoreDoc = new Document("type",score.getString("type"));
                    scoreDoc.append("score",score.getDouble("score"));
                    newScoresArray.add(scoreDoc);
                }               
            }           

        //Update the scores array for every student using student _id
        collection.updateOne(Filters.eq("_id", document.getInteger("_id")), new Document("$set",new Document("scores",newScoresArray)));
    }       
}

#11


0  

Certainly it's late, but I just want to contribute my own solution on Mongo Shell:

当然已经很晚了,但我只想对Mongo Shell提供我自己的解决方案:

var students = db.getCollection('students').find({});
for(i = 0 ; i < students.length(); i++) {
    var scores = students[i].scores;
    var tmp = [];
    var min = -1 ;
    var valueTmp = {};
    for(j = 0 ; j < scores.length; j++) {        
        if(scores[j].type != 'homework') {
            tmp.push(scores[j]);
        } else {
            if (min == -1) {
                min = scores[j].score;
                valueTmp = scores[j];
            } else {
                if (min > scores[j].score) {
                    min = scores[j].score;
                    tmp.push(valueTmp);
                    valueTmp = scores[j];
                } else {
                    tmp.push(scores[j]);
                }
            }
        }
    }
    db.students.updateOne({_id:students[i]._id},
                            {$set:{scores:tmp}});
}

#12


-1  

sort by the score can be simple like:

按分数排序可以很简单:

db.students.find({_id:137}).sort({score:-1}).pretty()

but you need to find the one for type:homework ...

但是你需要找到一个类型:家庭作业……

#13


-2  

it should be something like this:

应该是这样的:

db.students.find().sort(scores: ({"score":-1}));