복붙노트

[MONGODB] MongoDB의에서 수집 기록 내부 배열을 정렬하는 방법

MONGODB

MongoDB의에서 수집 기록 내부 배열을 정렬하는 방법

여기 MongoDB의 멍청한 놈 ...

'숙제'순으로 점수 : 좋아, 나는 학생의 수집, 다음과 같이 표시가 .... 나는 '유형'을 정렬 할 것을 기록과 각이있다.

몽고 쉘에 같은 그 주문의 모습은 무엇입니까?

> 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

그러나 그것은 작동하지 않습니다.

해결법

  1. ==============================

    1.당신은 MongoDB를 2.2에서 새로운 집계 프레임 워크를 사용하여 임베디드 응용 프로그램 코드의 배열 또는 조작해야합니다.

    당신은 MongoDB를 2.2에서 새로운 집계 프레임 워크를 사용하여 임베디드 응용 프로그램 코드의 배열 또는 조작해야합니다.

    몽고 쉘의 예 집계 :

    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
    }
    
  2. ==============================

    2.우리는 JS와 몽고 콘솔이 문제를 해결 수있는 방법의 그 :

    우리는 JS와 몽고 콘솔이 문제를 해결 수있는 방법의 그 :

    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.여기에 배열에서 가장 낮은 점수를 발견하고 제거하는 데 사용할 수있는 자바 코드입니다.

    여기에 배열에서 가장 낮은 점수를 발견하고 제거하는 데 사용할 수있는 자바 코드입니다.

    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. ==============================

    4.그것은 추측하기 쉬운 충분하지만 다음 기초를 이해하지 않기 때문에 어쨌든, 몽고의 대학 과정과 속임수 않으려 고.

    그것은 추측하기 쉬운 충분하지만 다음 기초를 이해하지 않기 때문에 어쨌든, 몽고의 대학 과정과 속임수 않으려 고.

    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. ==============================

    5.이 질문은 다른 방식으로 관리 할 수 ​​있기 때문에 내가 다른 해결책은 "삽입 및 종류"라고 말하고 싶은, 이런 식으로 당신이 찾기를 만든 것입니다 순간에 정렬 된 배열을 얻을 것이다 ().

    이 질문은 다른 방식으로 관리 할 수 ​​있기 때문에 내가 다른 해결책은 "삽입 및 종류"라고 말하고 싶은, 이런 식으로 당신이 찾기를 만든 것입니다 순간에 정렬 된 배열을 얻을 것이다 ().

    이 데이터를 고려 :

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

    여기에서 우리는, 문서를 업데이트 정렬을 만들 것입니다.

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

    결과는 다음과 같습니다

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

    선적 서류 비치: https://docs.mongodb.com/manual/reference/operator/update/sort/#up._S_sort

  6. ==============================

    6.숙제 3.1이 개 숙제 점수에서 낮은 하나를 제거하는 경우 개발자를위한 MongoDB를 : 나는 당신이 M101P을하고있다 생각합니다. 집계는 그 시점까지 가르쳐되지 않은 때문에이 같은 작업을 수행 할 수 있습니다 :

    숙제 3.1이 개 숙제 점수에서 낮은 하나를 제거하는 경우 개발자를위한 MongoDB를 : 나는 당신이 M101P을하고있다 생각합니다. 집계는 그 시점까지 가르쳐되지 않은 때문에이 같은 작업을 수행 할 수 있습니다 :

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

    7.정렬 배열 순서에서 다음 단계를 수행합니다

    정렬 배열 순서에서 다음 단계를 수행합니다

    1) 배열을 통해 반복 사용 풀림

    2) 정렬 어레이

    병합 3)를 사용하여 그룹은 하나 개의 어레이로 배열 물체

    4) 다음 다른 필드 프로젝트

    질문

    db.taskDetails.aggregate([
        {$unwind:"$counter_offer"},
        {$match:{_id:ObjectId('5bfbc0f9ac2a73278459efc1')}},
        {$sort:{"counter_offer.Counter_offer_Amount":1}},
       {$unwind:"$counter_offer"},
       {"$group" : {_id:"$_id",
        counter_offer:{ $push: "$counter_offer" },
        "task_name": { "$first": "$task_name"},
        "task_status": { "$first": "$task_status"},
        "task_location": { "$first": "$task_location"},
    }}
    
    ]).pretty()
    
  8. ==============================

    8.@Stennie의 대답은 아마 $ 그룹 운영자가 많은 문서 (점수 하나)에서 폭발하지 않고, 원본 문서를 유지하는 것이 유용 할 것, 괜찮습니다.

    @Stennie의 대답은 아마 $ 그룹 운영자가 많은 문서 (점수 하나)에서 폭발하지 않고, 원본 문서를 유지하는 것이 유용 할 것, 괜찮습니다.

    응용 프로그램에 대한 자바 스크립트를 사용하여 때 나는 또 다른 솔루션을 추가 할 수 있습니다.

    당신은 쿼리 하나의 문서는 대신 집계를하는, JS로 포함 된 배열을 정렬 때로는 쉽게합니다. 문서에 필드를 많이 가지고 때, 그렇지 않으면 당신은 하나 하나, 또는 사용 $$ ROOT 운영자가 모든 필드를 밀어했습니다, 더 나은 $ 푸시 연산자를 사용하는 것보다의 (내가 잘못?)

    내 예제 코드는 Mongoose.js을 사용합니다 : 당신은 당신이 학생 모델을 초기화 한 가정하자.

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

    9.나를 위해이 작품, 그것은 약간 거친 코드 있지만, 각 학생을위한 가장 낮은 작업의 결과는 정확합니다.

    나를 위해이 작품, 그것은 약간 거친 코드 있지만, 각 학생을위한 가장 낮은 작업의 결과는 정확합니다.

    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++
    }
    
  10. ==============================

    10.이 pyMongo, MongoDB를 파이썬 드라이버를 사용하여 내 접근 방식입니다 :

    이 pyMongo, MongoDB를 파이썬 드라이버를 사용하여 내 접근 방식입니다 :

    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()
    
  11. ==============================

    11.이것은 내가 (유무는 간단 그래서 이해하기 쉽게 것을 유지) 자바로 구현 한 방법입니다 -

    이것은 내가 (유무는 간단 그래서 이해하기 쉽게 것을 유지) 자바로 구현 한 방법입니다 -

    접근 :

    다음은 자바 코드를 노력하고 있습니다 :

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

    12.물론이 말,하지만 난 그냥 몽고 쉘에 내 자신의 솔루션을 공헌하고 싶다 :

    물론이 말,하지만 난 그냥 몽고 쉘에 내 자신의 솔루션을 공헌하고 싶다 :

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

    13.정렬 점수에 의해처럼 간단 할 수있다 :

    정렬 점수에 의해처럼 간단 할 수있다 :

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

    하지만 당신은 유형에 대한 하나 찾을 필요가 : 숙제를 ...

  14. ==============================

    14.그 결과는 아래와 같습니다 :

    그 결과는 아래와 같습니다 :

    db.students.find().sort(scores: ({"score":-1}));
    
  15. from https://stackoverflow.com/questions/13449874/how-to-sort-array-inside-collection-record-in-mongodb by cc-by-sa and MIT license