MongoDB의 Aggregation은 데이터 처리 파이프라인의 개념을 모델로 한다.
파이프라인(pipeline)이란 이전 단계의 연산 결과를 다음 단계 연산에 이용하는 것을 말한다.
Studio 3T for MongoDB에서도 Aggregate를 제공한다.
https://jaehun2841.github.io/2019/02/24/2019-02-24-mongodb-2/#sort
pipeline 순서
collection > $project > $match > $group > $sort > $skip > $limit > $unwind > $out
Meteor에서는 Server 쪽 Meteor.methods에 Aggregation 쿼리를 작성하고, Client 쪽 Meteor.call에서 리턴한 값을 받는 형태로 사용한다.
server.jsimport Orders from "../imports/collection/Orders";
Meteor.methods({
async getData() {
const raw = Orders.rawCollection();
const agrregate = Meteor.wrapAsync(raw.aggregate, raw);
const query = [
{
"$match": {
"isFruit": "true"
}
},
{
"$group": {
"_id": "$orderDate",
"sum_price": {
"$sum": "$amount"
}
}
},
{
"$sort": {
"_id": 1
}
},
];
const orders = aggregate(query, { "allowDiskUse" : false });
try {
return await orders.toArray();
} catch(e) {
console.log(e);
return [];
}
}
});
rawCollection() : Meteor 패키지에 의해 감싸져 있던 mongoDB를 native 상태로 돌린다.
wrapAsync() : 기본적으로 async, await로 구현되어 있다.
allowDiskUse : 메모리가 부족할 때 DISK를 사용할 수 있도록(true) 설정한다.
toArray() : aggregate 최신 버전은 결과 값이 Cursor로 리턴된다. 따라서 배열로 변환해준다.
client.jsMeteor.call("getData", (err, result) => {
if(err) {
console.log(err);
} else {
console.log('총 과일 가격: ', result);
}
});
ReactiveAggregate
https://github.com/robfallows/tunguska-reactive-aggregate
가장 처음 사용한 방식은 ReactiveAggregate였다.
하지만 많은 양의 데이터를 가져올 때 메모리 누수(Heap out memory)가 발생했다.
메모리 용량을 키우기 위해 Node를 실행할 때 NODE_OPTIONS=--max-old-space-size=8192 설정해 주었지만 역시나 같은 문제가 발생하였다.
ReactiveAggregate는 쿼리나 사용 자체에는 문제가 없지만, 메모리 누수가 일어난다.