Notepad
Published 2021. 11. 4. 13:26
MongoDB - 집계2 dev/DB

집계

1.도큐먼트 재구성

  • 집계 파이프라인은 도큐먼트를 변형하여 출력 도큐먼트를 생성하는데 사용할 수 있는 다양한 함수 제공

1.1 문자열 함수

  • $concat : 두 개 이상의 문자열을 단일 문자열로 연결
  • $strcasecmp : 대/소문자를 구분하지 않는 문자열 비교를 하며, 숫자를 반환
  • $substr : 문자열의 부분 문자열 반환
  • $toLower : 문자열을 모두 소문자로 변환
  • $toUpeer : 문자열을 모두 대문자로 변환
  • 예시
db.users.aggregate([
    {$match: {username: 'kbanker'}},
    {$project:
        {
            name: {$concat:['$first_name', ' ', '$last_name']}, // 공백으로 연결
            firstInitial: {$substr: ['$first_name',0,1]},       // 첫 번째 문자 반환
            usernameUpperCase: {$toUpper: '$username'}          // 대문자로 변경
        }
    }
])

// 결과
{
    "_id" : ObjectId("4c4b1476238d3b4dd5000001"),
    "name" : "Kyle Banker",
    "firstInitial" : "K",
    "usernameUpperCase" : "KBANKER"
}

1.2 산술 함수

  • $add : 배열 번호를 추가
  • $divide : 첫 번째 숫자를 두 번째 숫자로 나눈 값
  • $mod : 첫 번째 숫자의 나머지를 두 번째 숫자로 나눈 값
  • $multiply : 숫자 배열을 곱셈
  • $subtract : 첫 번째 숫자에서 두 번째 숫자를 뺀 값

1.3 날짜/시간 함수

  • $dayOfYear : 연 중의 일로서 1에서 366까지
  • $dayOfMonth : 월 중의 일로서 1에서 31까지
  • $dayOfWeek : 주 중의 일로서 1에서 7까지이며, 1은 일요일을 의미
  • $year : 날짜의 연 부분
  • $month : 날짜의 월 부분으로 1에서 12까지
  • $week : 연 중의 주로서, 0에서 53까지
  • $hour : 시간을 뜻하고, 0에서 23까지
  • $minute : 분을 뜻하고, 0에서 59까지
  • $second : 초를 뜻하고, 0에서 59까지(윤초는 60초)
  • $millisecond : 시간 중 밀리초를 뜻하며, 0에서 999까지

1.4 논리 함수

  • $and : 배열 내의 모든 값이 true의 경우는 true
  • $cmp : 두 개 값을 비교하여 결과값을 반환해 주며, 두 값이 동일하면 0을 반환
  • $cond : if .. then .. else 조건부 논리
  • $gt : 하나의 값이 다른 하나의 값보다 큰지의 여부 확인
  • $gte : 하나의 값이 다른 하나의 값보다 크거나 같은지의 여부 확인
  • $ifNull : null값/표현식을 지정된 값으로 변환
  • $lt : 하나의 값이 다른 하나의 값보다 작은지의 여부 확인
  • $lte : 하나의 값이 다른 하나의 값보다 작거나 같은지의 여부 확인
  • $eq : 두 값이 동일한지의 여부 확인
  • $ne : 두 값이 동일하지 않은지에 대한 여부 확인
  • $not : 주어진 값의 반대 조건을 반환. true -> false
  • $or : 배열의 값 중 그 어떤 하나라도 true 인 경우는 true

1.5 집합(Set) 함수

  • $setEquals : 두 개의 집합이 완전히 같은 요소를 가지는 경우 true
  • $setIntersection : 두 개의 집합에서 공통적으로 존재하는 요소의 배열을 반환. 교집합
  • $setDifference : 두 번째 집합에서 없는 첫 번째 집합의 요소를 반환. 차집합
  • $setUnion : 두 집합의 합집합을 반환
  • $setIsSubset : 두 번째 집합이 첫 번째 집합의 부분집합이면 true
  • $anyElementTrue : 집합의 요소 중 그 어느 하나라도 true 이면 true
  • $allElementTrue : 집합의 모든 요소가 true일 경우에만 true
  • $not : 주어진 값의 반대 조건을 반환. true -> false
  • $or : 배열의 값 중 그 어떤 하나라도 true 인 경우 true
  • 예시
// 샘플 도큐먼트 2건
{
     "_id" : ObjectId("4c4b1476238d3b4dd5003981"),
    "productName" : "Extra Large Wheel Barrow",
    "tags" : [ "tools", "gardening", "soil" ]
}
{
     "_id" : ObjectId("4c4b1476238d3b4dd5003982"),
    "productName" : "Rubberized Work Glove, Black",
    "tags" : [ "gardening" ]
}

// 실행
testSet1 = ['tools']
db.products.aggregate([
    {
        $project: {
            productName: '$name',
            tags:1,
            setUnion: {$setUnion:['$tags',testSet1]}, // testSet1을 포함한 합집합
        }
    }
])

// 결과
{
    "_id" : ObjectId("4c4b1476238d3b4dd5003981"),
    "productName" : "Extra Large Wheel Barrow",
    "tags" : ["tools", "gardening", "soil"],
    "setUnion" : ["gardening","tools","soil"]  // 합집합 결과
}
{
    "_id" : ObjectId("4c4b1476238d3b4dd5003982"),
    "productName" : "Rubberized Work Glove, Black",
    "tags" : ["gardening"],
    "setUnion" : ["tools", "gardening"]     // 합집합 결과
}

1.6 기타 함수

  • $meta : 텍스트 검색 관련 정보에 접근
  • $size : 배열의 크기를 반환
  • $map : 배열의 각 멤버에 표현식(expression)을 적용
  • $let : 표현식의 범위 내에서 사용되는 변수 정의
  • $literal : 표현식의 값을 평가하지 않고 반환

2. 집계 파이프라인 성능에 대한 이해

  • 성능에 중요한 영향을 미칠 수 있는 주요 고려사항
    • 파이프라인에서 간으한 한 빨리 도큐먼트의 수와 크기를 줄인다
    • 인덱스는 $match와 $sort 작업에서만 사용할 수 있고, 이러한 작업은 크게 가속화할 수 있다.
    • $match 또는 $sort 이외의 연산자를 파이프라인에서 사용한 후에는 인덱스를 사용할 수 없다.
    • sharding을 사용하는 경우(매우 큰 컬렉션의 경우 일반적인 방법) $match 및 $project 연산자는 개별 샤드에서 실행된다. 다른 연산자를 사용하면 남아 있는 파이프라인이 프라이머리 샤드에서 실행된다.

2.1 집계 파이프라인 옵션

  • aggregate 함수에 전달 할 수 있는 두 번째 매개 변수
    • explain() : 파이프라인을 실행하고 오직 파이프라인 프로세스 세부 정보만 반환
    • allowDiskUse : 중간 결과를 위해 디스크를 사용
    • cursor : 초기 배치 크기를 지정
  • 사용 예시
// 변수 선언
additionalOptions = {
    explain: true, 
    allowDiskUse: true, 
    cursor: { batchSize: n } 
};
// 파라미터 전달
db.collection.aggregate(pipeline, additionalOptions);

2.2 집계 파이프라인의 explain() 함수

  • SQL에서 볼 수 있는 EXPLAIN 함수와 유사한 함수
  • 파이프라인의 각 연산에 대한 explain 결과 반환
  • MongoDB 서버 버전에 따라 explain() 함수의 결과가 다를 수 있음
  • 예시
// 실행
> countsByRating = db.reviews.aggregate([
... {$match : {'product_id': product['_id']}}, // $match 먼저 실행
... {$group : { _id:'$rating',
... count:{$sum:1}}}
... ], {explain:true}); // explain 옵션 true

// 결과
// 인덱스 사용 여부 확인
// 인덱스 내 범위 스캔 여부 확인
{
    "stages" : [
        {
            "$cursor" : {
                "query" : {
                    "product_id" : ObjectId("4c4b1476238d3b4dd5003981")
                },
                "fields" : {
                    "rating" : 1,
                    "_id" : 0
                },
                "plan" : {
                    "cursor" : "BtreeCursor ", // 인덱스 기반 커서인 
                    "isMultiKey" : false,      // BTreeCursor 사용
                    "scanAndOrder" : false,
                    "indexBounds" : {
                        "product_id" : [       // 단위 제품에 사용되는 범위
                            [
                                ObjectId("4c4b1476238d3b4dd5003981"),
                                ObjectId("4c4b1476238d3b4dd5003981")
                            ]
                        ]
                    },
                    "allPlans" : [
                    ...
                    ]
                }
            }
        },
        {
            "$group" : {
                "_id" : "$rating",
                "count" : {
                    "$sum" : {
                        "$const" : 1
                    }
                }
            }
        }
    ],
    "ok" : 1
}

2.3 allowDiskUse 옵션

  • MongoDB는 블로킹 정렬 작업을 처리하는 동안 디스크의 임시 파일을 사용하여 100MB 시스템 메모리 제한을 초과하는 데이터를 저장 가능
  • allowDiskUse 옵션을 true로 사용해야 가능
  • allowDiskUse 옵션이 없다면 100MB 시스템 메모리 제한에 걸려서 에러 발생

2.4 집계 커서 옵션

  • v2.6부터는 Mongo 셸을 통해 MongoDB에 엑세스하는 경우 기본값은 커서를 반환
  • 기존 프로그램 손상 방지를 위해 파이프라인의 경우 예전과 같이 16MB로 제한된 단일 도큐먼트만 반환
  • 옵션을 추가하여 결과를 커서로 반환 가능
  • 예시
countsByRating = db.reviews.aggregate([
    {$match : {'product_id': product['_id']}},
    {$group : { _id:'$rating',
                count:{$sum:1}}}
],{cursor:{}}); // 커서 반환
  • 집계 파이프라인에서 반환된 커서의 지원 메소드
    • cursor.hasNext() : 결과에 다음 도큐먼트가 존재하는지 확인
    • cursor.nex() : 결과에서 다음 도큐먼트를 반환
    • cursor.toArray() : 전체 결과를 배열로 반환
    • cursor.forEach() : 결과의 각 행에 대해 함수 실행
    • cursor.map() : 결과의 각 행에 대해 함수를 실행하고, 함수 반환값의 배열 반환
    • cursor.itcount() : 항목수를 반환(테스트 전용)
    • cursor.pretty() : 형식을 갖춘 결과의 배열을 표시
    • cursor.objsLeftInBatch() : 현재 배치에 남아 있는 문서 수를 반환
  • 커서의 목적은 많은 양의 데이터를 스트리밍할 수 있게 해주는 것으로 메모리 관리에 장점

3. 기타 집계 기능

3.1 .count()와 .distinct()

  • count
    • db.collection.count(query, options)
  • distinct
    • db.collection.distinct(field, query, options)

출처

'dev > DB' 카테고리의 다른 글

MongoDB - 인덱스1  (0) 2021.12.23
MongoDB - 업데이트, 원자적 연산, 삭제  (0) 2021.11.11
MongoDB - 집계1  (0) 2021.10.28
MongoDB - Query Selectors(1)  (0) 2021.10.22
[MongoDB] 도큐먼트 지향 데이터  (0) 2021.10.15
profile

Notepad

@Apio

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!