1. 파이프라인, 단계 및 조정 기능 항목
- 집계 프레임워크는 몽고DB 내 분석 도구 모음으로, 하나 이상의 컬렉션에 있는 도큐먼트에 대한 분석을 수행하게 지원
- 집계 프레임워크는 파이프라인 개념을 기반으로 함
- 집계 파이프라인을 통해 몽고DB 컬렉션에서 입력을 받고, 컬렉션에서 나온 도큐먼트를 하나 이상의 단계를 거쳐 전달하며 단계마다 해당 입력에 다른 작업을 수행함
- 각 단계는 전 단계에서 생산한 출력이 무엇이든 입력으로 받아들임
- 모든 단계의 입력과 출력은 도큐먼트
- 집계 파이프라인은 bash와 같은 리눅스 셸 파이프라인과 매우 유사한 개념이며, 단계마다 특정 작업을 수행함
- 각 단계는 특정한 형태의 도큐먼트를 입력받고 특정 출력을 생성하는데, 출력은 도큐먼트 스트림
- 파이프라인 끝에서는 find 쿼리와 거의 같은 방식으로 출력에 접근
- 집계 파이프라인의 개별 단계는 데이터 처리 단위
- 한 번에 입력 도큐너트 스트림을 하나씩 가져와서
- 각 도큐먼트를 하나씩 처리하고
- 출력 도큐먼트 스트림을 하나씩 생성
- 각 단계는 knobs 또는 tunables 셋을 제공하며 해당 항목들을 조정해 각 단계를 매개변수로 지정함으로써 원하는 작업 수행 가능
- 이러한 tunables은 일반적으로 필드 수정 산술 연산, 도큐먼트 재구성, 일종의 누신 작업 등 여러 작업을 수행하는 연산자의 형태를 취함
- 동일한 유형의 단계를 단일 파이프라인의 여러 번 포함 가능
- i.g. 컬렉션 전체를 파이프라인에 전달하지 않도록 초기 필터를 수행한 뒤 추가 처리 과정을 거치고 다른 기준 셋을 적용해 추가로 필터링
2. 단계 시작하기: 익숙한 작업들
- aggregate는 집계 쿼리를 실행할 때 호출하는 메서드
- 집계를 위해 집계 파이프라인을 전달하는데, 파이프라인은 도큐먼트를 요소로 포함하는 배열
- 각 도큐먼트는 특정 단계 연산자를 규정해야 함
- i.g. 필터링을 위한 일치 단계와, 출력을 도큐먼트 당 두 개의 필드로 제한하는 산출 단계
- 주어진 몽고DB 버전에서 쿼리 플래너가 수행할 수 있는 최적화 유형에 관계없이 항상 집계 파이프라인의 효율성을 고려해야 함
- 파이프라인을 구축할 때 한 단계에서 다른 단계로 전달해야 하는 도큐먼트 수를 반드시 제한하는 것을 권장
- i.g. projection 하기 전에 limit부터 수행
- i.g. 순서가 중요하다면 limit 전에 sort부터 진행
- i.g. 처음 몇 개의 도큐먼트를 건너뛰어야 한다면 sort -> skip -> limit -> project 순
- 파이프라인을 구축할 때 한 단계에서 다른 단계로 전달해야 하는 도큐먼트 수를 반드시 제한하는 것을 권장
3. 표현식
집계 프레임워크는 다양한 표현식 클래스를 지원합니다.
- 불리언 표현식: AND, OR, NOT 표현식 사용 가능
- 집합 표현식: 배열을 집합으로 사용 가능 i.g. 2개 이상의 집합의 교집합이나 합집합을 얻을 수 있고 두 집합의 차를 이용해 여러 집합 연산을 수행 가능
- 비교 표현식: 다양한 유형의 범위 필터를 표현 가능
- 산술 표현식: ceiling, floor, 자연 록,, 그리고 로그를 계산할 수 있을 뿐 아니라 곱하기, 나누기, 더하기, 빼기와 같은 간단한 산술 연산 수행 가능
- 문자열 표현식: concatenate, substring 검색, 대소문자 및 텍스트 검색과 관련된 작업 수행 가능
- 배열 표현식: 배열 요소를 필터링, 분할 그리고 특정 배열에서 값의 범위를 가져오는 등 배열을 조작하는 데 유용함
- 가변적 표현식: 리터럴, 날짜 값 구문 분석을 위한 식, 조건식을 사용
- 누산기: 합계, 기술 통계 및 기타 여러 유형의 값을 계산하는 기능 제공
4. $project
- 중첩된 필드를 승격하면 중첩 구조를 제거하고 평면적인 필드 구조로 변환
- $문자는 선출 단계에서 값을 지정하는 데 사용, 해당 값이 필드 경로로 해석되고 각 필드에서 선출할 값을 선택하는 데 사용됨을 나타냄
부연 설명
- 출력에서 각 도큐먼트에는 "name" 필드와 "funders" 필드가 있으며 기업공개를 거친 회사는 "ipo"필드에 회사가 상장된 연도가 포함되며 "valuation" 필드에는 기업공개 당시 회사의 가치가 포함됨
- 모든 도큐먼트에서 해당 필드는 최상위 필드이며 피드 값은 중첩된 도큐먼트 및 배열에서 승격됨
- $ 문자는 선출 단계에서 ipo, valuation, funders에 대한 값을 지정하는 데 사용되며, 해당 값이 필드 경로로 해석되고 각 필드에서 선출한 값을 선택하는 데 사용됨을 나타냄
- funders에 대한 값이 여러 개 출력되었는데 사실 이는 배열의 배열
- 페이스북 예제 도큐먼트를 검토한 결과 모든 자금 지원자가 "investments"라는 배열에 나열됨
- 모든 펀딩 라운드에 대해 "investments" 배열 각 항목의 financial_org.permalink 값을 선출하도록 지정했으므로 자금 지원자 이름의 배열의 배열이 구성됨
5. $unwind
- 집계 파이프라인에서 배열 필드로 작업할 때는 종종 하나 이상의 전개 단계를 포함해야 하며 이를 통해 지정된 배열 필드의 각 요소에 대해 출력 도큐먼트가 하나씩 있는 출력을 생성할 수 있음
- $unwind를 먼저 적용한 후에 $match를 적용하는 것이 일반적
6. 배열 표현식
6.1 필터 표현식
- 필터 표현식은 필터 기준에 따라 배열에서 요소의 부분 집합을 선택
부연 설명
- roudns 필드는 필터 표현식을 사용
- $filter 연산자는 배열 필드와 함께 작동하도록 설계됨
- 첫 번째 옵션은 input이며 단순히 배열을 지정
- 두 번째 옵션은 나머지 필터 표현식 전체에서 "funding_rounds" 배열에 사용할 이름 지정
- 세 번째 옵션으로는 조건을 지정하며 조건은 입력으로 지정한 배열을 필터링하는 기준을 제공해 서브셋을 선택 (예제에서는 "funding_round"의 "raised_amount"가 1억 달러 이상인 요소만 선택하도록 필터링
- 조건을 지정할 때 $$를 사용했는데 $$는 작업 중인 표현식 내에서 정의된 변수를 참조하는 데 사용
- as 절은 필터 표현식 내에서 변수를 정의
- 이때 변수는 as 절에서 레이블링 한 대로 "round"라는 이름을 가지며 이는 필드 경로에서의 변수 참조를 명확히 하기 위함
6.2 배열 요소 연산자
- $arrayElemAt 연산자를 사용하면 배열 내 특정 슬롯에서 요소를 선택할 수 있음
부연 설명
- 선출할 필드를 정의하고 값으로 $arrayElemAt을 필드명으로 사용하고 두 요소 배열을 값으로 사용해 도큐먼트를 지정
- 첫 번째 요소는 선택하려는 필드를 지정하는 필드 경로
- 두 번째 요소는 우리가 원하는 배열 내에서 슬롯을 식별
$slice 표현식은 $arrayElemAt와 관련 있고 해당 표현식을 사용하면 배열의 특정 인덱스에서 시작해 하나뿐 아니라 여러 항목을 순서대로 반환할 수 있습니다.
배열에서 가장 일반적으로 수행되는 작업은 배열의 크기나 길이를 결정하는 작업이며 이는 $size 연산자로 수행할 수 있습니다.
7. 누산기
- 누산기는 본질적으로 표현식의 유형이지만 여러 도큐먼트에서 찾은 필드 값으로부터 값을 계산하므로 자체 클래스에서 고려함
- 집계 프레임워크가 제공하는 누산기를 사용하면 특정 필드의 모든 값 합산 ($sum), 평균 계산 ($avg) 등의 작업을 할 수 있음
- 또한 $first와 $last도 누산기로 간주하는데 표현식이 사용된 단계를 통과하는 모든 도큐먼트 내 값을 고려하기 때문
- $max와 $min은 도큐먼트 스트림을 고려해 표시되는 값 중 하나만 저장하는 누산기
- $mergeObjects를 사용하면 여러 도큐먼트를 하나의 도큐먼트로 결합 가능
- 배열용 누산기로 도큐먼트가 파이프라인 단계를 통과할 때 배열에 값을 $push 할 수 있음
- $addToSet은 $push와 유사하지만 결과 배열에 중복 값이 포함되지 않게 한다는 차이점 존재
- 몽고DB 3.2 이전에는 누산기를 그룹 단계에서만 사용할 수 있었지만 몽고DB 3.2는 선출 단계에서 누산기의 서브셋에 접근하는 기능을 도입함
- 선출 단계에서는 $sum, $avg와 같은 누산기가 단일 도큐먼트 내 배열에서 작동
- 그룹 단계에서는 누산기가 여러 도큐먼트 값에 걸쳐 계산을 수행할 수 있음
7,1 선출 단계에서 누산기 사용
부연 설명
- $funding_rounds의 값은 각 회사 도큐먼트 내 배열이므로 누산기를 사용할 수 있음
- 산출 단계에서 누산기는 배열값 필드에서 작동해야 함
- 배열에 포함된 도큐먼트에 도달하고 출력 도큐먼트에 최댓값을 선출함으로써 배열에서 가장 큰 값을 쉽게 식별 가능
부연 설명
- $sum 누산기를 사용해 컬렉션에 있는 각 회사의 총모금액을 계산
8. 그룹화 소개
- 예전부터 몽고DB 집계 프레임워크에서 누산기는 그룹 단계의 영역이었고 그룹 단계는 SQL GROUP BY 명령과 유사한 기능을 수행
- 그룹 단계에서는 여러 도큐먼트의 값을 함께 집계하고, 집계한 값에 평균 계산과 같은 집계 작업을 수행할 수 있음
- 아래 예제는 그룹 단계를 사용해 설립 연도를 기준으로 모든 회사를 합친 후 연도마다 평균 직원 수를 계산
부연 설명
- 구축한 파이프라인에는 그룹 단계와 정렬 단계의 두 단계가 있음
- 그룹 단계의 기본은 도큐먼트의 일부로 지정하는 "_id" 필드이며 이는 매우 엄격한 해석을 사용하는 $group 연산자 자체의 값
- 해당 필드를 사용해 그룹 단계에서 표시되는 도큐먼트를 구성하는 데 사용하는 내용을 정의
- 그룹 단계가 첫 번째이므로 aggregate 명령은 companies 컬렉션의 모든 도큐먼트를 그룹 단계를 통해 전달
- 그룹 단계에서는 "founded_year"에 대해 동일한 값을 갖는 모든 도큐먼트를 단일 그룹으로 취급
- 필드의 값을 구성하는 단계에서는 $avg 누산기를 사용해 "founded_year"가 동일한 모든 회사의 평균 직원 수를 계산
8.1 그룹 단계의 _id 필드
부연 설명
- 출력에는 "_id"와 "companies"라는 두 필드가 있는 도큐먼트가 있음
- 각 도큐먼트는 회사 목록을 포함하는데 "founded_year"는 회사 설립 연도이고 "companies"는 회사 이름의 배열
- "_id" 필드를 구성할 때 설립 연도를 바로 제공하지 않고 "founded_year"라고 레이블링 된 필드가 있는 도큐먼트에 넣는 이유는 그룹 값에 레이블을 지정하지 않을 경우 회사 설립 연도를 기준으로 그룹화한다는 점이 분명하지 않기 때문
- 혼동을 피하려면 그룹화할 값에 명시적으로 레이블을 지정하는 것을 권장
가. 여러 필드로 구성된 도큐먼트가 _id 값인 방식
- 경우에 따라 여러 필드로 구성된 도큐먼트가 _id 값인 방식 사용 가능
- 아래 예제에서는 설립 연도와 카테고리 코드를 기준으로 도큐먼트를 그룹화
8.2 그룹 vs 선출
부연 설명
- funding_rounds 배열이 비어 있지 않은 도큐먼트를 필터링하며 시작한 뒤 funding_rounds를 전개
- 따라서 정렬 및 그룹 단계에서는 각 회사의 funding_rounds 배열의 각 요소에 대해 하나의 도큐먼트가 표시됨
- 예제 파이프라인의 정렬 단계는 연도, 월, 일을 기준으로 모두 오름차순으로 정렬을 수행하며 이는 단계가 가장 오래된 펀딩 라운드로부터 출력함을 의미
- 정렬 단계 다음의 그룹 단계에서는 회사 이름별로 그룹화를 수행한 뒤 $push 누산기를 사용해 정렬된 펀딩 라운드 배열을 구성
- $push 표현식은 그룹 단계가 도큐먼트의 입력 스트림을 가져와 각 도큐먼트를 차례로 처리해 값을 축적하도록 설계되었기 때문에 그룹 단계에서만 작동
- 반면에 선출 단계는 입력 스트림의 각 도큐먼트에 대해 개별적으로 작동함
- 정렬 단계에서 전체적으로 모든 펀딩 라운드를 정렬했으므로 각 회사에 대해 funding_rounds 배열이 정렬됨
9. 집계 파이프라인 결과를 컬렉션에 쓰기
- 집계 파이프라인에서 생성된 도큐먼트를 컬렉션에 쓸 수 있는 두 가지 단계로 $out와 $merge가 있음
- 두 단계 중 하나만 사용할 수 있으며, 이는 집계 파이프라인의 마지막 단계여야 함
- $out에는 몇 가지 제약 사항이 있음
- 동일한 데이터베이스에만 쓸 수 있고
- 기존 컬렉션이 있으면 덮어쓰며
- 샤딩된 컬렉션에는 사용 불가능
- $merge는 몽고DB 4.2에서 도입됐으며 가능하다면 컬렉션에 쓰기를 수행할 때 선호되는 단계
- $merge는 샤딩 여부에 관계없이 모든 데이터베이스와 컬렉션에 사용 가능
- $merge는 기존 컬렉션으로 작업할 때 결과를 통합할 수 있음
- $merge를 사용할 때 진정한 장점은 파이프라인 실행 시 출력 컬렉션의 내용이 점진적으로 갱신되는 주문식의 구체화된 뷰를 생성할 수 있음
참고
몽고DB 완벽 가이드 3판 - 한빛미디어
반응형
'DB > 몽고DB 완벽 가이드 3판' 카테고리의 다른 글
[9장] 애플리케이션 설계 (0) | 2025.04.21 |
---|---|
[8장] 트랜잭션 (0) | 2025.04.16 |
[6장] 특수 인덱스와 컬렉션 유형 (0) | 2025.04.10 |
[5장] 인덱싱 (0) | 2025.04.04 |
[4장] 쿼리 (0) | 2025.03.29 |