46

scores生徒のコレクションがあり、それぞれに次のようなレコードがあり、配列を の降順で並べ替えたいと考えていますscore

その呪文はモンゴシェルでどのように見えますか?

> 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
                }
        ]
}

私はこの呪文を試しています....

 doc = db.students.find()

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

しかし、それは機能していません。

4

16 に答える 16

60

アプリケーション コードで埋め込み配列を操作するか、MongoDB 2.2の新しいAggregation Frameworkを使用する必要があります。

mongoシェルでの集約の例:

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

出力例:

{
    "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
}
于 2012-11-19T13:45:31.480 に答える
6

これが、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});
  })
于 2015-06-16T09:41:22.510 に答える
3

配列内の最低スコアを見つけて削除するために使用できる 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();
    }
}
}
于 2014-04-05T12:02:29.007 に答える
1

推測するのは簡単ですが、基本を理解できないので、モンゴ大学のコースでカンニングをしないようにしてください。

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

});
于 2015-08-22T21:40:18.047 に答える
0

あなたはM101P: MongoDB for Developers宿題 3.1 が 2 つの宿題の点数から低い方の点数を削除することを行っていると思います。その時点まで集計は教えられていないので、次のようなことができます:

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}})
于 2016-04-10T18:22:06.890 に答える
-1

これは私にとってはうまくいきます。少し大まかなコードですが、各生徒の最低のタスクの結果は正しいです。

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++
}
于 2015-11-01T19:09:08.280 に答える
-1

これは私がJavaで実装した方法です(理解しやすいようにシンプルにしています)-

アプローチ :

  1. 学生コレクションからスコア配列を取得する
  2. タイプ == 宿題であるスコア配列からすべてのスコア値を取得します
  3. スコア値を最も低いものが1番目の要素になるように並べ替える [score.get(0)]
  4. 次に、メインのスコアをループして、スコア配列の新しいコピーを作成し、type == homework && score == score.get(0)の要素をスキップします。
  5. 最後に、新しいスコア配列を学生ドキュメントに更新します。

以下は動作中の 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)));
    }       
}
于 2017-01-29T07:25:18.370 に答える
-4

次のようになります。

db.students.find().sort(scores: ({"score":-1}));
于 2012-11-19T08:17:49.537 に答える