복붙노트

[MONGODB] MongoDB를 집계 쿼리는 $ 합계를 사용하여 적절한 금액을 반환하지 않습니다

MONGODB

MongoDB를 집계 쿼리는 $ 합계를 사용하여 적절한 금액을 반환하지 않습니다

나는 다음과 같은 형식의 문서와 컬렉션 학생을 가지고있다 -

{
 _id:"53fe74a866455060e003c2db",
 name:"sam",
 subject:"maths",
 marks:"77"
}
{
 _id:"53fe79cbef038fee879263d2",
 name:"ryan", 
 subject:"bio",
 marks:"82"
}
{
 _id:"53fe74a866456060e003c2de",
 name:"tony",
 subject:"maths",
 marks:"86"
}

나는 제목 = "수학"과 학생들 모두의 전체 표시의 수를 싶어. 그래서 나는 합계로 163을 얻어야한다.

db.students.aggregate([{ $match : { subject : "maths" } },
{ "$group" : { _id : "$subject", totalMarks : { $sum : "$marks" } } }])

지금은 다음에서 그 결과를 얻어야한다

{"result":[{"_id":"53fe74a866455060e003c2db", "totalMarks":163}], "ok":1}

하지만 GET-

{"result":[{"_id":"53fe74a866455060e003c2db", "totalMarks":0}], "ok":1}

내가 여기에 잘못된 일을 할 수있는 무엇을 누군가 지점 수 있습니까?

해결법

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

    1.현재 스키마는 문자열로 표시 필드 데이터 형식을 가지고 있으며, 당신은 합을 작동하도록 통합 프레임 워크에 대한 정수 데이터 형식이 필요합니다. 그것의지도 기능의 개체 속성에에서는 parseInt와 같은 기본 자바 스크립트 방법 ()의 사용을 허용하기 때문에 다른 한편으로는, 당신은 합계를 계산하는 맵리 듀스를 사용할 수 있습니다. 그래서 전반적으로 두 가지 방법이 있습니다.

    현재 스키마는 문자열로 표시 필드 데이터 형식을 가지고 있으며, 당신은 합을 작동하도록 통합 프레임 워크에 대한 정수 데이터 형식이 필요합니다. 그것의지도 기능의 개체 속성에에서는 parseInt와 같은 기본 자바 스크립트 방법 ()의 사용을 허용하기 때문에 다른 한편으로는, 당신은 합계를 계산하는 맵리 듀스를 사용할 수 있습니다. 그래서 전반적으로 두 가지 방법이 있습니다.

    첫 번째는 스키마를 변경하거나 실제 수치가 아닌 문자열 표현을이 문서에서 다른 필드를 추가하는 것입니다. 컬렉션의 문서 크기가 상대적으로 작은 경우, MongoDB의의 커서 찾기 (), 대해 forEach () 및 업데이트 () 귀하의 마크 스키마를 변경하는 방법의 조합을 사용할 수 있습니다 :

    db.student.find({ "marks": { "$type": 2 } }).snapshot().forEach(function(doc) {
        db.student.update(
            { "_id": doc._id, "marks": { "$type": 2 } }, 
            { "$set": { "marks": parseInt(doc.marks) } }
        );
    });
    

    상대적으로 큰 수집 크기를 들어, DB의 성능이 저하 될 것입니다 그리고 이것에 대한 몽고 대량 업데이트를 사용하는 것이 좋습니다 :

    MongoDB의 버전> = 2.6 <3.2

    var bulk = db.student.initializeUnorderedBulkOp(),
        counter = 0;
    
    db.student.find({"marks": {"$exists": true, "$type": 2 }}).forEach(function (doc) {    
        bulk.find({ "_id": doc._id }).updateOne({ 
            "$set": { "marks": parseInt(doc.marks) } 
        });
    
        counter++;
        if (counter % 1000 === 0) {
            // Execute per 1000 operations 
            bulk.execute(); 
    
            // re-initialize every 1000 update statements
            bulk = db.student.initializeUnorderedBulkOp();
        }
    })
    
    // Clean up remaining operations in queue
    if (counter % 1000 !== 0) bulk.execute(); 
    

    MongoDB를 버전 3.2 및 최신 :

    var ops = [],
        cursor = db.student.find({"marks": {"$exists": true, "$type": 2 }});
    
    cursor.forEach(function (doc) {     
        ops.push({ 
            "updateOne": { 
                "filter": { "_id": doc._id } ,              
                "update": { "$set": { "marks": parseInt(doc.marks) } } 
            }         
        });
    
        if (ops.length === 1000) {
            db.student.bulkWrite(ops);
            ops = [];
        }     
    });
    
    if (ops.length > 0) db.student.bulkWrite(ops);
    

    두 번째 방법을 사용하면 자바 스크립트 함수에서는 parseInt를 사용할 수있는 맵리 듀스와 쿼리를 다시 작성하는 것입니다 ().

    당신의 맵리 듀스 작업에서 각 입력 문서를 처리하는 map 함수를 정의합니다. 이 기능은 각 문서의 제목에 변환 된 마크 문자열 값을 매핑하고 피사체와 변환 된 마크 쌍을 방출한다. 자바 스크립트 기본 기능으로 parseInt ()가 적용 할 수있는 곳이다. 주 : 함수, 이는 맵 감소 연산 처리되는 문서를 말한다 :

    var mapper = function () {
        var x = parseInt(this.marks);
        emit(this.subject, x);
    };
    

    다음으로, 두 개의 인자 keySubject valuesMarks과 함께 기능을 줄일 대응 정의한다. valuesMarks는 해당 요소를지도 기능에 의해 출사 keySubject 그룹화 부호 정수 값이다 배열이다. 이 함수는 해당 요소의 합으로 valuesMarks 어레이를 감소시킨다.

    var reducer = function(keySubject, valuesMarks) {
        return Array.sum(valuesMarks);
    };
    
    db.student.mapReduce(
        mapper,
        reducer,
        {
            out : "example_results",
            query: { subject : "maths" }       
        }
     );
    

    컬렉션으로, 위의 새 컬렉션의 db.example_results에 맵리 듀스 집계 결과를 둘 것이다. 따라서 db.example_results.find ()가 출력 :

    /* 0 */
    {
        "_id" : "maths",
        "value" : 163
    }
    
  2. ==============================

    2.당신의 합이 0이 반환되고 가능한 원인은 다음과 같습니다

    당신의 합이 0이 반환되고 가능한 원인은 다음과 같습니다

  3. from https://stackoverflow.com/questions/29561380/mongodb-aggregate-query-isnt-returning-proper-sum-on-using-sum by cc-by-sa and MIT license