db.collection.aggregate()
드라이버가 포함된 MongoDB
이 페이지에서는 mongosh
메서드에 대해 설명합니다. MongoDB 드라이버에서 동일한 메서드를 보려면 해당 프로그래밍 언어의 해당 페이지를 참조하세요.
정의
호환성
다음 환경에서 호스팅되는 배포에 db.collection.aggregate()
사용할 수 있습니다.
MongoDB Atlas: 클라우드에서의 MongoDB 배포를 위한 완전 관리형 서비스
MongoDB Enterprise: MongoDB의 구독 기반 자체 관리 버전
MongoDB Community: MongoDB의 소스 사용 가능 무료 자체 관리 버전
구문
aggregate()
메서드의 형식은 다음과 같습니다.
db.collection.aggregate( <pipeline>, <options> )
aggregate()
메서드는 다음 매개변수를 사용합니다.
Parameter | 유형 | 설명 |
---|---|---|
| 배열 | 데이터 애그리게이션 작업 또는 단계의 시퀀스입니다. 자세한 내용은 집계 파이프라인 연산자 를 참조하세요. 메서드는 여전히 파이프라인 단계를 배열의 요소가 아닌 별도의 인수로 허용할 수 있습니다. 그러나 |
| 문서 | 선택 사항. 가 |
행동
Error Handling
오류가 발생하면 aggregate()
헬퍼가 예외를 발생시킵니다.
커서 동작
mongosh
에서는 db.collection.aggregate()
에서 반환된 커서가 var
키워드를 사용하여 변수에 할당되지 않으면 mongosh
가 커서를 자동으로 최대 20번 반복합니다. mongosh
에서 커서를 처리하려면
mongosh
에서 커서 반복을 참조하세요.
집계에서 반환된 커서는 다음 메서드와 같이 평가된 커서(즉, 첫 번째 배치가 조회된 커서)에서 작동하는 커서 메서드만 지원합니다.
자세한 내용은 다음을 참조하세요.
세션
세션 내에서 생성된 커서의 경우 세션 외부에서 getMore
을(를) 호출할 수 없습니다.
마찬가지로 세션 외부에서 만든 커서의 경우 세션 내부에서 getMore
를 호출할 수 없습니다.
세션 유휴 시간 초과
MongoDB 드라이버와 mongosh
는 승인되지 않은 쓰기 작업을 제외한 모든 작업을 서버 세션과 연결합니다. 세션과 명시적으로 연결되지 않은 작업(예: Mongo.startSession()
사용)의 경우, MongoDB 드라이버와 mongosh
는 암시적 세션을 생성하고 이를 작업과 연결합니다.
세션이 30분 이상 유휴 상태인 경우, MongoDB 서버는 해당 세션을 만료된 것으로 표시하고 언제든지 세션을 종료할 수 있습니다. MongoDB 서버가 세션을 종료하면 진행 중인 모든 작업과 해당 세션과 관련된 열린 커서도 종료됩니다. 여기에는 noCursorTimeout()
또는 30분보다 큰 maxTimeMS()
로 구성된 커서가 포함됩니다.
커서를 반환하는 작업의 경우 커서가 30분 이상 유휴 상태일 수 있는 경우 명시적 세션 내에서 Mongo.startSession()
을 사용하여 작업을 실행하고 refreshSessions
명령을 사용하여 세션을 주기적으로 새로 고칩니다. 자세한 내용은 세션 유휴 시간 초과를 참조하세요.
트랜잭션
db.collection.aggregate()
는 분산 트랜잭션 내에서 사용할 수 있습니다.
그러나 다음 단계는 트랜잭션 내에서 허용되지 않습니다.
explain
옵션도 지정할 수 없습니다.
트랜잭션 외부에서 생성된 커서의 경우 트랜잭션 내부에서
getMore
을(를) 호출할 수 없습니다.트랜잭션에서 생성된 커서의 경우 트랜잭션 외부에서
getMore
를 호출할 수 없습니다.
중요
대부분의 경우 분산 트랜잭션은 단일 문서 쓰기에 비해 더 큰 성능 비용이 발생하므로 분산 트랜잭션의 가용성이 효과적인 스키마 설계를 대체할 수는 없습니다. 대부분의 시나리오에서 비정규화된 데이터 모델 (내장된 문서 및 배열) 은 계속해서 데이터 및 사용 사례에 최적일 것입니다. 즉, 대부분의 시나리오에서 데이터를 적절하게 모델링하면 분산 트랜잭션의 필요성이 최소화됩니다.
추가 트랜잭션 사용 고려 사항(예: 런타임 제한 및 oplog 크기 제한)은 프로덕션 고려사항을 참조하세요.
클라이언트 연결 해제
db.collection.aggregate()
또는 $out
단계를 포함하지 $merge
않는 작업의 경우:
MongoDB 4.2부터 db.collection.aggregate()
를 발급한 클라이언트가 작업이 완료되기 전에 연결을 끊는 경우, MongoDB는 db.collection.aggregate()
를 사용하여 를killOp
을 종료로 표시합니다.
쿼리 설정
버전 8.0에 추가 되었습니다.
쿼리 설정을 사용하여 인덱스 힌트를 설정하고, 작업 거부 필터 및 기타 필드를 설정할 수 있습니다. 해당 설정은 전체 클러스터의 쿼리 형태에 적용됩니다. 클러스터는 종료 후에도 설정을 유지합니다.
쿼리 옵티마이저는 쿼리 계획 중 추가 입력으로 쿼리 설정을 사용하여 쿼리를 실행할 계획에 영향을 미칩니다. 쿼리 설정을 사용하여 쿼리 형태를 차단할 수도 있습니다.
쿼리 설정을 추가하고 예시를 살펴보려면 setQuerySettings
를 참조하세요.
find
, distinct
및 aggregate
명령에 대한 쿼리 설정을 추가할 수 있습니다.
쿼리 설정은 더 많은 기능을 제공하며 더 이상 사용되지 않는 인덱스 필터보다 선호됩니다.
쿼리 설정을 제거 하려면 removeQuerySettings
를 사용합니다. 쿼리 설정을 가져오려면 집계 파이프라인 에서 $querySettings
단계를 사용합니다.
예시
다음 예시에서는 다음 문서가 포함된 orders
컬렉션을 사용합니다.
db.orders.insertMany( [ { _id: 1, cust_id: "abc1", ord_date: ISODate("2012-11-02T17:04:11.102Z"), status: "A", amount: 50 }, { _id: 2, cust_id: "xyz1", ord_date: ISODate("2013-10-01T17:04:11.102Z"), status: "A", amount: 100 }, { _id: 3, cust_id: "xyz1", ord_date: ISODate("2013-10-12T17:04:11.102Z"), status: "D", amount: 25 }, { _id: 4, cust_id: "xyz1", ord_date: ISODate("2013-10-11T17:04:11.102Z"), status: "D", amount: 125 }, { _id: 5, cust_id: "abc1", ord_date: ISODate("2013-11-12T17:04:11.102Z"), status: "A", amount: 25 } ] )
그룹화 및 합계 계산
다음 집계 작업은 상태가 "A"
와 같은 문서를 선택하고, 일치하는 문서를 cust_id
필드를 기준으로 그룹화하고, amount
필드의 합계에서 각 cust_id
필드의 total
을 계산하고, total
필드를 기준으로 결과를 내림차순으로 정렬합니다.
db.orders.aggregate( [ { $match: { status: "A" } }, { $group: { _id: "$cust_id", total: { $sum: "$amount" } } }, { $sort: { total: -1 } } ] )
이 연산은 다음 문서가 있는 커서를 반환합니다.
[ { _id: "xyz1", total: 100 }, { _id: "abc1", total: 75 } ]
mongosh
는 반환된 커서를 자동으로 반복하여 결과를 인쇄합니다. mongosh
에서 커서를 수동으로 처리하려면
mongosh
에서 커서 반복을 참조하세요.
집계 파이프라인 작업에 대한 정보 반환
다음 예시에서는 db.collection.explain()
를 사용하여 집계 파이프라인의 실행 계획에 대한 자세한 정보를 확인합니다.
db.orders.explain().aggregate( [ { $match: { status: "A" } }, { $group: { _id: "$cust_id", total: { $sum: "$amount" } } }, { $sort: { total: -1 } } ] )
이 작업은 집계 파이프라인 처리 를 자세히 설명하는 문서 를 반환합니다. 예를 예시, 문서 에는 사용된 작업에 대한 인덱스(해당하는 경우) 등의 세부 정보가 표시될 수 있습니다. [1] orders
컬렉션 이 샤딩된 컬렉션 인 경우 이 문서 에는 샤드와 병합 작업 간의 분업과 대상 쿼리의 경우 대상 샤드도 표시됩니다.
참고
explain
출력 문서의 대상 독자는 기계가 아닌 사람이며 출력 형식은 출시 간에 변경될 수 있습니다.
executionStats
또는 allPlansExecution
설명 모드를 db.collection.explain()
메서드에 전달하여 더 자세한 설명 출력을 볼 수 있습니다.
[1] | 인덱스 필터는 사용된 인덱스의 선택에 영향을 줄 수 있습니다. 자세한 내용은 인덱스 필터를 참조하세요. |
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
옵션에 다음 구문을 사용합니다.
cursor: { batchSize: <int> }
예를 들어 다음 집계 작업은 커서의 초기 배치 크기를 0
(으)로 지정합니다.
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
필드를 사용합니다.
mongosh
는 반환된 커서를 자동으로 반복하여 결과를 인쇄합니다. mongosh
에서 커서를 수동으로 처리하려면
mongosh
에서 커서 반복을 참조하세요.
데이터 정렬 지정
데이터 정렬을 사용하면 대소문자 및 악센트 표시 규칙과 같은 문자열 비교에 대한 언어별 규칙을 지정할 수 있습니다.
컬렉션 restaurants
에는 다음 문서가 있습니다.
db.restaurants.insertMany( [ { _id: 1, category: "café", status: "A" }, { _id: 2, category: "cafe", status: "a" }, { _id: 3, category: "cafE", status: "a" } ] )
다음 집계 작업에는 데이터 정렬 옵션이 포함됩니다.
db.restaurants.aggregate( [ { $match: { status: "A" } }, { $group: { _id: "$category", count: { $sum: 1 } } } ], { collation: { locale: "fr", strength: 1 } } );
참고
$lookup
또는 $graphLookup
과 같이 여러 뷰를 포함하는 집계를 수행하는 경우 뷰의 데이터 정렬이 동일해야 합니다.
필드에 대한 설명은 데이터 정렬 문서를 참조하세요.
인덱스 힌트
다음 문서를 사용하여 컬렉션 food
를 생성합니다.
db.food.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.food.createIndex( { qty: 1, type: 1 } ); db.food.createIndex( { qty: 1, category: 1 } );
다음 집계 작업에는 지정된 인덱스를 강제로 사용하는 hint
옵션이 포함되어 있습니다.
db.food.aggregate( [ { $sort: { qty: 1 }}, { $match: { category: "cake", qty: 10 } }, { $sort: { type: -1 } } ], { hint: { qty: 1, category: 1 } } )
readConcern
재정의
작업에 대한 읽기 고려를 지정하려면 readConcern
옵션을 사용합니다.
$out
또는 $merge
단계는 읽기 고려 "linearizable"
과 함께 사용할 수 없습니다. 즉, db.collection.aggregate()
에
"linearizable"
읽기 고려를 지정하면 파이프라인에 둘 중 그 어떤 단계도 포함할 수 없습니다.
복제본 세트에 대한 다음 작업은 대부분의 노드에 기록된 것으로 확인된 데이터의 가장 최근 복제본을 읽을 수 있도록 "majority"
의 읽기 고려를 지정합니다.
참고
단일 스레드가 자신의 쓰기를 읽을 수 있도록 하려면 복제본 세트의 프라이머리에 대해
"majority"
읽기 고려 및"majority"
쓰기 고려를 사용합니다.$out
단계를 포함하는 집계에 대해 읽기 고려(read concern)레벨
"majority"
(을)를 지정할 수 있습니다.
읽기 고려 수준에 관계없이 노드의 최신 데이터는 시스템에 있는 데이터의 최신 버전을 반영하지 않을 수 있습니다.
db.restaurants.aggregate( [ { $match: { rating: { $lt: 5 } } } ], { readConcern: { level: "majority" } } )
댓글 지정
movies
이라는 이름의 collection에는 다음과 같이 형식이 지정된 문서가 포함되어 있습니다.
db.movies.insertOne( { _id: ObjectId("599b3b54b8ffff5d1cd323d8"), title: "Jaws", year: 1975, imdb: "tt0073195" } )
다음 집계 작업에서는 1995년에 제작한 동영상을 찾고 logs
, db.system.profile
collection, db.currentOp
에 추적 정보를 제공하는 comment
옵션을 포함합니다.
db.movies.aggregate( [ { $match: { year : 1995 } } ], { comment : "match_all_movies_from_1995" } ).pretty()
프로파일링을 활성화한 시스템에서는 아래와 같이 system.profile
컬렉션을 쿼리하여 최근의 모든 유사한 집계를 볼 수 있습니다.
db.system.profile.find( { "command.aggregate": "movies", "command.comment" : "match_all_movies_from_1995" } ).sort( { ts : -1 } ).pretty()
그러면 다음 형식의 프로파일러 결과 집합이 반환됩니다.
{ "op" : "command", "ns" : "video.movies", "command" : { "aggregate" : "movies", "pipeline" : [ { "$match" : { "year" : 1995 } } ], "comment" : "match_all_movies_from_1995", "cursor" : { }, "$db" : "video" }, ... }
애플리케이션은 시스템에서 특정 작업을 더 쉽게 추적하거나 식별할 수 있도록 주석에 임의의 정보를 인코딩할 수 있습니다. 예를 들어 애플리케이션은 프로세스 ID, 스레드 ID, 클라이언트 호스트 이름 및 명령을 실행한 사용자를 포함하는 문자열 주석을 첨부할 수 있습니다.
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.cakeSales.aggregate( [ { $match: { $expr: { $gt: [ "$salesTotal", "$$targetTotal" ] } } } ], { let: { targetTotal: 3000 } } )