Document를 집계하는 방법
- DB의 모든 정보를 불러와 Application 단계에서 집계하는 방법
- 네트워크 프로토콜을 통해MongoDB 외부로 정보를 넘겨야 하기 때문에 모든 Document로 인해 메모리 적재 + 네트워크 비용 발생
- MongoDB의 맵-리듀스 기능 이용
- Java Script 엔진과 정보 교환을 위해 메모리 사용 (BSON to Javascript로 변환)
- 사용자 쿼리에 대한 결과 필드를 가져와, 별도의 Thread에서 JavaScript를 실행(Aggregation도 비슷하지만, JS Thread가 아닌 C++로 실행되어 훨씬 빠름)
- JSMode라는 설정을 사용하면 속도는 빨라지지만, 대량의 메모리가 필요
- JSMode : false
- Javascript 엔진에서 다시 MongoDB내부로 정보를 보내는 과정이 추가
- JSMode : true
- Javascript 엔진 내에서 Document를 grouping 하는 작업을 수행
- Reduce 작업
- 그룹핑된 Document 내에서 연산을 진행
- JS Engine에서 수행
- 자유도가 높아, MongoDB 내부에서 아직 유지중
- 단, 다양한 집계 파이프라인의 명령어가 추가되면서 맵-리듀스 방식보다 더 많이 사용(Aggregation을 사용 못하는 경우 사용)
- MongoDB의 집계 파이프라인 기능을 이용
- Document를 순차적으로 받아서 집계 처리를 MongoDB 내부에서 진행(적은 메모리로 빠른 속도 성능)
- 순차적으로 받아서 처리하면 정확한 데이터가 맞을지..?
- 전부 받아 오는 것은 동일한데, 메모리에 모두 올려서 처리할 것인지, 하나씩 받아서 처리하는 것의 차이?
|
Application |
Map-Reduce |
Pipeline |
비고 |
자유도 |
좋다 |
좋다 |
나쁘다 |
|
처리 속도 |
가장 나쁘다. |
보통 |
가장 좋다 |
pipeline 이 map-reduce 보다 10배 더 빠름 |
램 사용량 |
매우 높음 |
높음 |
낮음 |
|
처리 위치 |
App. 내부 |
자바스크립트 엔진 |
MongoDB 내부 |
|
참고 : https://stackoverflow.com/questions/32131828/mongo-map-reduce-or-aggregate-strategy
https://stackoverflow.com/questions/13908438/is-mongodb-aggregation-framework-faster-than-map-reduce
Aggreration 이란?
- 여러 Document 들을 grouping하여 계산하여, 단일 결과를 반환
- Aggregation, Map-reduce, 단일 목적 Aggregation이 존재
- 처리 단계의 출력이 다음 단계의 입력으로 이어지는 형태로 연결된 구조 (linked list)
- 누적으로 계산하는 형태
- 주요 파이프라인
- 출처 : "맛있는 MongoDB"
git clone https://github.com/Karoid/mongodb_tutorials.git
cd mongodb_tutorials/operating_expenses/
mongoimport -d operatin_expenses -c population --file population.json
mongoimport -d operatin_expenses -c city_or_province --file city_or_province.json
mongoimport -d operatin_expenses -c operating_expenses -c local --file local.json
Stage |
설명 |
형식 |
$project |
어떤 필드를 숨기고, 어떤 필드를 새로 만들지 정하는 역할 |
{$project:{필드 : bollean}} {$project:{필드 : expression}} |
$group |
_id 값으로 지정된 내용이 같은 Document끼리 그룹화 |
{$group: {_id:expression, field1:{accumulator1:expression1},...}} |
$match |
Document를 필터링해서 반환. find문과 비슷한 역할 |
{$match:{쿼리}} |
$unwind |
입력 Document에서 배열 필드를 분해하여 각 요소에 대한 Document로 분리하여 출력 |
{$unwind:필드경로} { $unwind : { path:필드경로, includeArrayIndex:문자, preserveNullAndEmptyArrays: bollean } } |
$out |
파이프라인의 결과를 Collection에 기록 |
{ $out: "컬렉션명"} |
$group
연산자 |
설명 |
예시 |
$first |
그룹의 첫 번째 값을 반환. $sort 를 해야 의미가 있음 |
{ $group : { _id:"$그룹대상", 원하는필드명:{$first:"$값필드"} } }
(max와 동일하다고 생각했지만 결과 값이 살짝 다름)
db.population.aggregate({$group:{_id:"$city_or_province",population:{$first:"$population"}}}) |
$last |
그룹의 마지막 값을 반환. $sort 를 해야 의미가 있음 |
{ $group : { _id:"$그룹대상", 원하는필드명:{$last:"$값필드"} } }
(min와 동일하다고 생각했지만 결과 값이 살짝 다름) db.population.aggregate({$group:{_id:"$city_or_province",population:{$last:"$population"}}}) |
$max |
그룹에서 해당 필드의 최대 값을 반환 |
{ $group : { _id:"$그룹대상", 원하는필드명:{$max:"$값필드"} } } db.population.aggregate({$group:{_id:"$city_or_province",population:{$max:"$population"}}}) |
$min |
그룹에서 해당 필드의 최소 값을 반환 |
{ $group : { _id:"$그룹대상", 원하는필드명:{$min:"$값필드"} } } db.population.aggregate({$group:{_id:"$city_or_province",population:{$min:"$population"}}}) |
$avg |
그룹에서 해당 필드의 평균 값을 반환 |
{ $group : { _id:"$그룹대상", 원하는필드명:{$avg:"$값필드"} } } |
$sum |
그룹에서 해당 필드의 합산 값을 반환 |
{ $group : { _id:"$그룹대상", 원하는필드명:{$sum:"$값필드"} } }
db.population.aggregate({$group:{_id:"$city_or_province",population:{$sum:"$population"}}}) |
$push |
그룹에서 해당 필드의 모든 값을 배열에 넣어 반환. 중복을 제거하지 않음 |
{ $group : { _id:"$그룹대상", 원하는필드명:{$push:"$값필드"} } }
db.population.aggregate({$group:{_id:"$city_or_province",population:{$push:"$population"}}}) |
$addToSet |
그룹에서 해당 필드의 모든 값을 배열에 넣어 반환. 반환하는 배열에 중복된 요소가 없음 |
{ $group : { _id:"$그룹대상", 원하는필드명:{$addToSet:"$값필드"} } }
db.population.aggregate({$group:{_id:"$city_or_province",population:{$addToSet:"$population"}}}) |
- 샘플 데이터
$match
- find 명령어와 비슷
#rating 이 4보다 크거나 같은 내역, id들을 배열의 형태로 정리하도록 명령($push)
> db.rating.aggregate([
{$match: {rating: {$gte:4}}}
, {$group: {_id: "$rating", user_ids:{$push:"$user_id"}}}
])
$unwind
- 하나의 Document에 들어있는 배열 요소들을 각각의 Document에 하나의 값으로 갖도록 만드는 작업
'MongoDB > MongoDB-Study_완료' 카테고리의 다른 글
[MongoDB] [Study-10] Lock & Transactions (0) | 2021.04.16 |
---|---|
[MongoDB] [Study-9] Index (0) | 2021.04.16 |
[MongoDB][Study-7] Find / FindAndModify / Cursor (0) | 2021.03.28 |
[MongoDB] [Study-6] MongoDB CRUD 쓰기 연산 (0) | 2021.03.28 |
[MongoDB] [Study-Break] Cursor 간략한 정리 (0) | 2021.03.27 |