집계
정의
aggregate
집계 파이프라인을 사용하여 집계 작업을 수행합니다. 파이프라인을 통해 사용자는 일련의 단계 기반 조작으로 컬렉션 또는 기타 소스의 데이터를 처리할 수 있습니다.
팁
mongosh
에서 이 명령은db.aggregate()
및db.collection.aggregate()
헬퍼 메서드 또는watch()
헬퍼 메서드를 통해 실행할 수도 있습니다.
헬퍼 메서드는
mongosh
사용자에게 편리하지만 데이터베이스 명령과 동일한 수준의 정보를 반환하지 못할 수 있습니다. 편의가 필요하지 않거나 추가 리턴 필드가 필요한 경우 데이터베이스 명령을 사용합니다.
호환성
이 명령은 다음 환경에서 호스팅되는 배포에서 사용할 수 있습니다.
MongoDB Atlas: 클라우드에서의 MongoDB 배포를 위한 완전 관리형 서비스
중요
이 명령은 M0, M2 및 M5 클러스터에서 제한적으로 지원 됩니다. 자세한 내용은 지원되지 않는 명령을 참조하세요.
MongoDB Enterprise: MongoDB의 구독 기반 자체 관리 버전
MongoDB Community: MongoDB의 소스 사용 가능 무료 자체 관리 버전
구문
버전 5.0에서 변경됨
명령은 다음과 같은 구문을 가집니다:
db.runCommand( { aggregate: "<collection>" || 1, pipeline: [ <stage>, <...> ], explain: <boolean>, allowDiskUse: <boolean>, cursor: <document>, maxTimeMS: <int>, bypassDocumentValidation: <boolean>, readConcern: <document>, collation: <document>, hint: <string or document>, comment: <any>, writeConcern: <document>, let: <document> // Added in MongoDB 5.0 } )
명령 필드
aggregate
명령은 다음 필드를 인수로 사용합니다.
필드 | 유형 | 설명 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
| 문자열 | 집계 파이프라인의 입력 역할을 하는 컬렉션 또는 뷰의 이름입니다. 컬렉션에 구애받지 않는 명령에는 | ||||||||||
| 배열 | 문서 스트림을 집계 파이프라인의 일부로 처리하고 변환하는 집계 파이프라인 단계의 배열입니다. | ||||||||||
| 부울 | 선택 사항. 파이프라인 처리에 대한 정보를 반환하도록 지정합니다. 다중 문서 트랜잭션에서는 사용할 수 없습니다. | ||||||||||
| 부울 | 선택 사항. 이 옵션을 사용하여 특정 쿼리에 대한
MongoDB 6.0부터 자세한 내용은 프로파일러 로그 메시지 및 진단 로그 메시지에는 메모리 제한 | ||||||||||
| 문서 | 커서 객체 생성을 제어하는 옵션이 포함된 문서를 지정합니다. MongoDB
| ||||||||||
| non-negative integer | 선택 사항. 시간 제한을 밀리초 단위로 지정합니다. MongoDB는 | ||||||||||
| 부울 | |||||||||||
| 문서 | 선택 사항. 읽기 고려를 지정합니다.
가능한 읽기 고려 수준은 다음과 같습니다.
읽기 고려 수준에 대한 자세한 내용은 읽기 고려 수준을 참조하세요.
| ||||||||||
| 문서 | 선택 사항. 작업에 사용할 데이터 정렬을 지정합니다. 데이터 정렬을 사용하면 대소문자 및 악센트 표시 규칙과 같은 문자열 비교에 대한 언어별 규칙을 지정할 수 있습니다. 데이터 정렬 옵션의 구문은 다음과 같습니다:
데이터 정렬을 지정할 때 데이터 정렬이 지정되지 않았지만 컬렉션에 기본 데이터 정렬이 있는 경우( 컬렉션 또는 연산에 대한 데이터 정렬이 지정되지 않은 경우, MongoDB는 이전 버전에서 문자열 비교에 사용된 간단한 이진 비교를 사용합니다. 한 연산에 대해 여러 데이터 정렬을 지정할 수 없습니다. 예를 들어 필드별로 서로 다른 데이터 정렬을 지정할 수 없으며 정렬과 함께 찾기를 수행하는 경우 찾기 와 정렬에서 각각 다른 데이터 정렬을 사용하는 것은 허용되지 않습니다. | ||||||||||
| 문자열 또는 문서 | 선택 사항. 집계에 사용할 인덱스입니다. 인덱스는 집계가 실행되는 초기 컬렉션/뷰에 있습니다. 인덱스 이름 또는 인덱스 사양 문서로 인덱스를 지정합니다.
| ||||||||||
| any | 선택 사항. 이 명령에 첨부할 사용자 제공 코멘트입니다. 설정되면 이 설명은 다음 위치에서 이 명령의 레코드와 함께 표시됩니다.
댓글은 유효한 모든 BSON types (문자열, 정수, 객체, 배열 등)이 될 수 있습니다.
| ||||||||||
| 문서 | |||||||||||
| 문서 | 선택 사항. 변수 목록이 있는 문서를 지정합니다. 이를 통해 쿼리 텍스트에서 변수를 분리하여 명령 가독성을 향상시킬 수 있습니다. 문서 구문은 다음과 같습니다:
변수는 표현식에서 반환된 값으로 설정되며 이후에는 변경할 수 없습니다. 명령에서 변수 값에 액세스하려면 변수를 사용하여 파이프라인 및 변수를 사용하는 전체 예시 버전 5.0에 추가. |
MongoDB는 cursor
옵션 없이
aggregate
명령을 사용하는 것을 제거합니다. 단, 명령에
explain
옵션이 포함된 경우는 제외됩니다. explain
옵션을 포함하지 않으면 커서 옵션을 지정해야 합니다.
기본 배치 크기로 커서를 표시하려면
cursor: {}
을 지정합니다.기본 배치 크기가 아닌 커서를 표시하려면
cursor: { batchSize: <num> }
을 사용합니다.
집계 파이프라인에 대한 자세한 내용은 다음을 참조하세요.
세션
세션 내에서 생성된 커서의 경우 세션 외부에서 getMore
을(를) 호출할 수 없습니다.
마찬가지로 세션 외부에서 만든 커서의 경우 세션 내부에서 getMore
를 호출할 수 없습니다.
세션 유휴 시간 초과
MongoDB 드라이버와 mongosh
는 승인되지 않은 쓰기 작업을 제외한 모든 작업을 서버 세션과 연결합니다. 세션과 명시적으로 연결되지 않은 작업(예: Mongo.startSession()
사용)의 경우, MongoDB 드라이버와 mongosh
는 암시적 세션을 생성하고 이를 작업과 연결합니다.
세션이 30분 이상 유휴 상태인 경우, MongoDB 서버는 해당 세션을 만료된 것으로 표시하고 언제든지 세션을 종료할 수 있습니다. MongoDB 서버가 세션을 종료하면 진행 중인 모든 작업과 해당 세션과 관련된 열린 커서도 종료됩니다. 여기에는 noCursorTimeout()
또는 30분보다 큰 maxTimeMS()
로 구성된 커서가 포함됩니다.
커서를 반환하는 작업의 경우 커서가 30분 이상 유휴 상태일 수 있는 경우 명시적 세션 내에서 Mongo.startSession()
을 사용하여 작업을 실행하고 refreshSessions
명령을 사용하여 세션을 주기적으로 새로 고칩니다. 자세한 내용은 세션 유휴 시간 초과를 참조하세요.
트랜잭션
aggregate
는 분산 트랜잭션 내에서 사용할 수 있습니다.
그러나 다음 단계는 트랜잭션 내에서 허용되지 않습니다.
explain
옵션도 지정할 수 없습니다.
트랜잭션 외부에서 생성된 커서의 경우 트랜잭션 내부에서
getMore
을(를) 호출할 수 없습니다.트랜잭션에서 생성된 커서의 경우 트랜잭션 외부에서
getMore
를 호출할 수 없습니다.
중요
대부분의 경우 분산 트랜잭션은 단일 문서 쓰기에 비해 더 큰 성능 비용이 발생하므로 분산 트랜잭션의 가용성이 효과적인 스키마 설계를 대체할 수는 없습니다. 대부분의 시나리오에서 비정규화된 데이터 모델 (내장된 문서 및 배열) 은 계속해서 데이터 및 사용 사례에 최적일 것입니다. 즉, 대부분의 시나리오에서 데이터를 적절하게 모델링하면 분산 트랜잭션의 필요성이 최소화됩니다.
추가 트랜잭션 사용 고려 사항(예: 런타임 제한 및 oplog 크기 제한)은 프로덕션 고려사항을 참조하세요.
클라이언트 연결 해제
aggregate
또는 $out
단계를 포함하지 $merge
않는 작업의 경우:
MongoDB 4.2부터 aggregate
를 발급한 클라이언트가 작업이 완료되기 전에 연결을 끊는 경우, MongoDB는 aggregate
를 사용하여 를killOp
을 종료로 표시합니다.
쿼리 설정
버전 8.0에 추가 되었습니다.
쿼리 설정을 사용하여 인덱스 힌트를 설정하고, 작업 거부 필터 및 기타 필드를 설정할 수 있습니다. 해당 설정은 전체 클러스터의 쿼리 형태에 적용됩니다. 클러스터는 종료 후에도 설정을 유지합니다.
쿼리 옵티마이저는 쿼리 계획 중 추가 입력으로 쿼리 설정을 사용하여 쿼리를 실행할 계획에 영향을 미칩니다. 쿼리 설정을 사용하여 쿼리 형태를 차단할 수도 있습니다.
쿼리 설정을 추가하고 예시를 살펴보려면 setQuerySettings
를 참조하세요.
You can add query settings for find
, distinct
,
and aggregate
commands.
쿼리 설정은 더 많은 기능을 제공하며 더 이상 사용되지 않는 인덱스 필터보다 선호됩니다.
쿼리 설정을 제거 하려면 removeQuerySettings
를 사용합니다. 쿼리 설정을 가져오려면 집계 파이프라인 에서 $querySettings
단계를 사용합니다.
Stable API
Stable API V1을 사용하는 경우:
aggregate
명령에서는 다음 단계를 사용할 수 없습니다.aggregate
명령에
explain
필드를 포함하지 마세요. 이를 포함하면 서버에서 APIStrictError 오류를 반환합니다.
$collStats
단계를 사용하는 경우count
필드만 사용할 수 있습니다. 다른$collStats
필드는 사용할 수 없습니다.
예시
MongoDB는 cursor
옵션 없이
aggregate
명령을 사용하는 것을 제거합니다. 단, 명령에
explain
옵션이 포함된 경우는 제외됩니다. explain
옵션을 포함하지 않으면 커서 옵션을 지정해야 합니다.
기본 배치 크기로 커서를 표시하려면
cursor: {}
을 지정합니다.기본 배치 크기가 아닌 커서를 표시하려면
cursor: { batchSize: <num> }
을 사용합니다.
대부분의 사용자는 aggregate
명령을 직접 실행하는 대신 mongosh
에 제공된
db.collection.aggregate()
헬퍼 또는 드라이버에서 동등한 도우미를 사용해야 합니다. 2.6 이상에서는
db.collection.aggregate()
헬퍼가 항상 커서를 반환합니다.
명령 구문을 보여주는 처음 두 가지 예시를 제외하고 이 페이지의 예시에서는 db.collection.aggregate()
헬퍼를 사용합니다.
다단계 파이프라인을 통한 데이터 애그리게이션
컬렉션 articles
에는 다음과 같은 문서가 포함되어 있습니다.
{ _id: ObjectId("52769ea0f3dc6ead47c9a1b2"), author: "abc123", title: "zzz", tags: [ "programming", "database", "mongodb" ] }
다음 예시에서는 articles
컬렉션에 대해
aggregate
연산을 수행하여 컬렉션에 나타나는
tags
배열의 각 고유 요소의 개수를 계산합니다.
db.runCommand( { aggregate: "articles", pipeline: [ { $project: { tags: 1 } }, { $unwind: "$tags" }, { $group: { _id: "$tags", count: { $sum : 1 } } } ], cursor: { } } )
mongosh
에서 이 작업은 다음과 같이 db.collection.aggregate()
도우미를 사용할 수 있습니다.
db.articles.aggregate( [ { $project: { tags: 1 } }, { $unwind: "$tags" }, { $group: { _id: "$tags", count: { $sum : 1 } } } ] )
관리 데이터베이스에서 $currentOp 사용
다음 예는 관리 데이터베이스에서 두 단계로 구성된 파이프라인을 실행합니다. 첫 번째 단계에서는 $currentOp
ㅈㅏㄱ업을 실행하고 두 번째 단계에서는 해당 작업의 결과를 필터링합니다.
db.adminCommand( { aggregate : 1, pipeline : [ { $currentOp : { allUsers : true, idleConnections : true } }, { $match : { shard : "shard01" } } ], cursor : { } } )
참고
aggregate
명령은 컬렉션을 지정하지 않고 대신 {aggregate: 1}
형식을 취합니다. 초기 $currentOp
단계가 컬렉션에서 입력을 가져오지 않기 때문입니다. 이는 나머지 파이프라인이 사용하는 자체 데이터를 생성합니다.
이처럼 컬렉션이 없는 집계를 실행하는 데 도움이 되는 새로운 db.aggregate()
헬퍼가 추가되었습니다. 위의 집계는 이 예시처럼 실행할 수도 있습니다.
집계 작업에 대한 정보 반환
다음 집계 작업은 선택적 필드인 explain
을 true
로 설정하여 집계 작업에 대한 정보를 반환합니다.
db.orders.aggregate([ { $match: { status: "A" } }, { $group: { _id: "$cust_id", total: { $sum: "$amount" } } }, { $sort: { total: -1 } } ], { explain: true } )
참고
explain 출력은 릴리스 간에 변경될 수 있습니다.
allowDiskUseByDefault
과의 상호작용
MongoDB 6.0부터는 실행에 100메가바이트 이상의 메모리가 필요한 파이프라인 단계에서 기본적으로 임시 파일을 디스크에 씁니다. 이러한 임시 파일은 파이프라인 실행 기간 동안 지속되며 인스턴스의 스토리지 공간에 영향을 줄 수 있습니다. MongoDB의 이전 버전에서는 이 동작을 활성화하려면 개별 find
및 aggregate
명령에 { allowDiskUse: true }
을(를) 전달해야 합니다.
개별 find
및 aggregate
명령은 다음 방법 중 하나를 통해 allowDiskUseByDefault
매개변수를 재정의할 수 있습니다:
1}이 로 설정된 경우 을 사용하여 임시 파일을 디스크에 쓰는 것을 허용합니다.
{ allowDiskUse: true }
allowDiskUseByDefault
false
1}이 로 설정된 경우 을 사용하여 임시 파일을 디스크에 쓰는 것을 금지합니다.
{ allowDiskUse: false }
allowDiskUseByDefault
true
프로파일러 로그 메시지 및 진단 로그 메시지에는 메모리 제한으로 인해 집계 단계에서 임시 파일에 데이터를 쓴 경우
usedDisk
표시기가 포함됩니다.
배치 크기 지정 데이터 집계
초기 배치 크기를 지정하려면 다음 예와 같이 cursor
필드에 batchSize
를 지정합니다.
db.orders.aggregate( [ { $match: { status: "A" } }, { $group: { _id: "$cust_id", total: { $sum: "$amount" } } }, { $sort: { total: -1 } }, { $limit: 2 } ], { cursor: { batchSize: 0 } } )
초기 배치 크기의 크기를 지정하는
{ cursor: { batchSize: 0 } }
문서는 비어 있는 첫 번째 배치를 나타냅니다. 이 배치 크기는 중요한 서버 쪽 작업을 수행하지 않고 커서 또는 오류 메시지를 빠르게 반환하는 데 유용합니다.
후속 getMore
작업(초기 배치 이후)에 대한 배치 크기를 지정하려면 getMore
명령을 실행할 때
batchSize
필드를 사용합니다.
데이터 정렬 지정
데이터 정렬을 사용하면 대소문자 및 악센트 표시 규칙과 같은 문자열 비교에 대한 언어별 규칙을 지정할 수 있습니다.
컬렉션 myColl
에는 다음 문서가 있습니다.
{ _id: 1, category: "café", status: "A" } { _id: 2, category: "cafe", status: "a" } { _id: 3, category: "cafE", status: "a" }
다음 집계 작업에는 데이터 정렬 옵션이 포함됩니다.
db.myColl.aggregate( [ { $match: { status: "A" } }, { $group: { _id: "$category", count: { $sum: 1 } } } ], { collation: { locale: "fr", strength: 1 } } );
필드에 대한 설명은 데이터 정렬 문서를 참조하세요.
인덱스 힌트
다음 문서를 사용하여 컬렉션 foodColl
를 생성합니다.
db.foodColl.insertMany( [ { _id: 1, category: "cake", type: "chocolate", qty: 10 }, { _id: 2, category: "cake", type: "ice cream", qty: 25 }, { _id: 3, category: "pie", type: "boston cream", qty: 20 }, { _id: 4, category: "pie", type: "blueberry", qty: 15 } ] )
다음 인덱스를 만듭니다:
db.foodColl.createIndex( { qty: 1, type: 1 } ); db.foodColl.createIndex( { qty: 1, category: 1 } );
다음 집계 작업에는 지정된 인덱스를 강제로 사용하는 hint
옵션이 포함되어 있습니다.
db.foodColl.aggregate( [ { $sort: { qty: 1 }}, { $match: { category: "cake", qty: 10 } }, { $sort: { type: -1 } } ], { hint: { qty: 1, category: 1 } } )
기본 읽기 고려 재정의
기본 읽기 고려 수준을 재정의하려면 readConcern
옵션을 사용하세요. getMore
명령은 원래 aggregate
명령에 지정된
readConcern
수준을 사용합니다.
$out
또는 $merge
단계는 읽기 고려 "linearizable"
과 함께 사용할 수 없습니다. 즉, db.collection.aggregate()
에 "linearizable"
읽기 고려를 지정하면 파이프라인에 둘 중 그 어떤 단계도 포함할 수 없습니다.
복제본 세트에 대한 다음 작업은 대부분의 노드에 기록된 것으로 확인된 데이터의 가장 최근 복제본을 읽을 수 있도록 "majority"
의 읽기 고려를 지정합니다.
중요
$out
단계를 포함하는 집계에 대해 읽기 고려(read concern)레벨
"majority"
(을)를 지정할 수 있습니다.
읽기 고려 수준에 관계없이 노드의 최신 데이터는 시스템에 있는 데이터의 최신 버전을 반영하지 않을 수 있습니다.
db.restaurants.aggregate( [ { $match: { rating: { $lt: 5 } } } ], { readConcern: { level: "majority" } } )
단일 스레드가 자신의 쓰기를 읽을 수 있도록 하려면 복제본 세트의 프라이머리에 대해 "majority"
읽기 고려 및 "majority"
쓰기 고려를 사용합니다.
let
에서 변수 사용
버전 5.0에 추가.
명령의 다른 곳에서 액세스할 수 있는 변수를 정의하려면 let
옵션을 사용합니다.
케이크 맛에 대한 판매가 포함된 컬렉션 cakeSales
를 생성합니다.
db.cakeSales.insertMany( [ { _id: 1, flavor: "chocolate", salesTotal: 1580 }, { _id: 2, flavor: "strawberry", salesTotal: 4350 }, { _id: 3, flavor: "cherry", salesTotal: 2150 } ] )
다음 예제입니다.
salesTotal
가 3000보다 큰 케이크(_id
가 2인 케이크)를 검색합니다.let
에서targetTotal
변수를 정의하고,$gt
에서$targetTotal
으로 참고됩니다.
db.runCommand( { aggregate: db.cakeSales.getName(), pipeline: [ { $match: { $expr: { $gt: [ "$salesTotal", "$$targetTotal" ] } } }, ], cursor: {}, let: { targetTotal: 3000 } } )