복붙노트

[MONGODB] 키 ID와 같은 MongoDB를 합산 기

MONGODB

키 ID와 같은 MongoDB를 합산 기

수 :이 키와 집계 함수의 결과를 얻을 수 있습니까?

예:

나는 다음과 같은 집계 쿼리를 가지고 :

db.users.aggregate([
  {
    $group: {
      _id: "$role",
      count: {
        $sum: 1
      }
    }
  }
])

그래서 결과는 올 :

{ "_id" : "moderator", "count" : 469 }
{ "_id" : "superadmin", "count" : 1 }
{ "_id" : "user", "count" : 2238 }
{ "_id" : "admin", "count" : 11 }

그 모든 괜찮지 만하고 결과는 다음과 같이 표시의 (아마도 $ 프로젝트를 사용) 방법이 그래서 (즉, 키와 값으로 계산과 역할) :

{ "moderator": 469 }
{ "superadmin": 1 }
{ "user": 2238 }
{ "admin": 11 }

나는 후 처리 JS와 함께 결과를에 의해 분명히 그렇게 할 수 있지만 내 목표는 집계 함수를 통해 직접 그렇게하는 것입니다.

해결법

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

    1.MongoDB를 3.6 및 최신으로, 당신은 원하는 결과를 얻을 $ arrayToObject 연산자와 $의 replaceRoot 파이프 라인의 사용을 활용할 수 있습니다. 다음과 같은 집계 파이프 라인을 실행해야합니다 :

    MongoDB를 3.6 및 최신으로, 당신은 원하는 결과를 얻을 $ arrayToObject 연산자와 $의 replaceRoot 파이프 라인의 사용을 활용할 수 있습니다. 다음과 같은 집계 파이프 라인을 실행해야합니다 :

    db.users.aggregate([
        { 
            "$group": {
                "_id": { "$toLower": "$role" },
                "count": { "$sum": 1 }
            }
        },
        { 
            "$group": {
                "_id": null,
                "counts": {
                    "$push": {
                        "k": "$_id",
                        "v": "$count"
                    }
                }
            }
        },
        { 
            "$replaceRoot": {
                "newRoot": { "$arrayToObject": "$counts" }
            } 
        }    
    ])
    

    이전 버전의 경우, $ 그룹 파이프 라인 단계에서 $ 콘드 운영자는 역할 필드 값을 기준으로 카운트를 평가하기 위해 효율적으로 사용할 수 있습니다. 전체 집계 파이프 라인은 원하는 형식으로 결과를 다음과 같이 구성 할 수있다 :

    db.users.aggregate([    
        { 
            "$group": { 
                "_id": null,             
                "moderator_count": {
                    "$sum": {
                        "$cond": [ { "$eq": [ "$role", "moderator" ] }, 1, 0 ]
                    }
                },
                "superadmin_count": {
                    "$sum": {
                        "$cond": [ { "$eq": [ "$role", "superadmin" ] }, 1, 0 ]
                    }
                },
                "user_count": {
                    "$sum": {
                        "$cond": [ { "$eq": [ "$role", "user" ] }, 1, 0 ]
                    }
                },
                "admin_count": {
                    "$sum": {
                        "$cond": [ { "$eq": [ "$role", "admin" ] }, 1, 0 ]
                    }
                } 
            }  
        },
        {
            "$project": {
                "_id": 0, 
                "moderator": "$moderator_count",
                "superadmin": "$superadmin_count",
                "user": "$user_count",
                "admin": "$admin_count"
            }
        }
    ])
    

    당신이 역할을 모르는 사전에 동적으로 파이프 라인 어레이를 생성하려는 경우 코멘트의 흔적에서, 역할 필드에 별개의 명령을 실행합니다. 이렇게하면 서로 다른 역할의 목록을 포함하는 객체를 줄 것이다 :

    var result = db.runCommand ( { distinct: "users", key: "role" } )
    var roles = result.values;
    printjson(roles); // this will print ["moderator", "superadmin", "user",  "admin"]
    

    이제 위의리스트에 근거 해, 당신은 자바 스크립트의 감소 () 메소드를 사용하여 설정 한 속성이있을 것이다 객체를 생성하여 파이프 라인을 조합 할 수 있습니다. 다음은이 보여줍니다

    var groupObj = { "_id": null },
        projectObj = { "_id": 0 }
    
    var groupPipeline = roles.reduce(function(obj, role) { // set the group pipeline object 
        obj[role + "_count"] = {
            "$sum": {
                "$cond": [ { "$eq": [ "$role", role ] }, 1, 0 ]
            }
        };
        return obj;
    }, groupObj );
    
    var projectPipeline = roles.reduce(function(obj, role) { // set the project pipeline object 
        obj[role] = "$" + role + "_count";
        return obj;
    }, projectObj );
    

    로 최종 집계 파이프 라인에서이 두 문서를 사용합니다 :

    db.users.aggregate([groupPipeline, projectPipeline]);
    

    아래의 데모를 확인하십시오.

    VAR 역할 = [ "중재자", "최고 관리자", "사용자", "관리자"], groupObj = { "_id": 널 (null)}, projectObj = { "_id"0}; VAR groupPipeline roles.reduce = (함수 (OBJ 역할) {// 그룹 파이프 객체 세트 OBJ [역할 + "_count"] = { "$ 합": { "$ COND": [{ "$ 이퀄라이저"[ "$ 역할"역할]}, 1, 0] } }; OBJ 반환; } groupObj); VAR projectPipeline = roles.reduce (기능 (OBJ, 역할) {// 프로젝트 파이프 라인 개체를 설정 OBJ [역할] = "$"+ 역할 + "_count"; OBJ 반환; } projectObj); VAR 파이프 = groupPipeline, projectPipeline] pre.innerHTML = JSON.stringify (파이프, NULL, 4); <프리 이드 = "사전">

  2. ==============================

    2.당신이 사용할 수있는지도를-감소 :

    당신이 사용할 수있는지도를-감소 :

    db.users.mapReduce(
      function map() { emit(this.role, 1); },
      function reduce(key, values) {
        var sum = 0;
        for (var i = 0; i < values.length; i++) {
          sum += i;
        }
        return sum;
      },
      {
          out: { inline: 1 },
          finalize: function (key, reducedValue) {
              var obj = {};
              obj[key] = reducedValue;
              return obj;
          }
      }
    )
    

    단지 값을 매핑

  3. from https://stackoverflow.com/questions/33503966/mongodb-group-and-sum-with-id-as-key by cc-by-sa and MIT license