몽고디비를 사용하다 보면 Array 타입의 데이터를 다룰 일이 생깁니다.
문제는 Array 안에 또 다른 Array가 배열로 존재하고 있는 경우 조작하기가 까다로워지죠.
이런 경우의 어려움을 겪는 분이 혹시나 있을까 싶어
오늘은 유용하게 활용할 수 있는 aggregate 함수 예제를 소개 해드릴까 합니다.
위의 data를 aggregate를 활용하여 다양한 조건을 만족하는 값을 조회해보겠습니다.
1. 우선 NeccesaryParam의 값이 nec이고 year는 2019 그리고 month는 7인 값만 뽑아오겠습니다.
(테스트 용도이기에 데이터 타입을 String으로 맞췄지만 보통은 int롤 맞춰줍니다.)
db.getCollection('test').aggregate([
{$match : { "NeccesaryParam": "nec", "year" : "2019", "month" : "7" } },
])
2. 이어서 array 안에 있는 속성 값 하나를 기준으로 내림차순(정렬)을 하기위해 array를 풀어줍니다($unwind 제한자 활용).
db.getCollection('test').aggregate([
{$match : { "NeccesaryParam": "nec", "year" : "2019", "month" : "7" } },
{$unwind: '$bookList'},
])
3. 위 같이 array로 묵였있던 값을 Object를 변환하여 $sort 제한자가 적용될 수 있도록 작업을 하고,
Object 안의 하나의 속성 값을 기준으로 내림(-1) 혹은 올림(1) 차순으로 정렬하면 됩니다.
db.getCollection('test').aggregate([
{$match : { "NeccesaryParam":"nec","year":"2019","month":"7"}},
{$unwind: '$bookList'},
{$sort: { 'bookList.rank' : -1}},
])
이전에 $unwind를 하지 않으면 $sort 제한자는 적용되지 않습니다.
4. 이후 group하기 전에 페이징 처리를 하고 싶다면 $group 전에 $skip과 $limit를 적용합니다.
db.getCollection('test').aggregate([
{$match : { "NeccesaryParam":"nec","year":"2019","month":"7"}},
{$unwind: '$bookList'},
{$sort: { 'bookList.rank' : 1}},
{$skip:2},
{$limit:3},
])
5. 마지막으로 작업을 맞추고 본래의 array로 재그룹화를 한다. 이때 $group 안에 $push라는 제한자를 쓰는 것에 주목하자
db.getCollection('test').aggregate([
{$match : { "NeccesaryParam":"nec","year":"2019","month":"7"}},
{$unwind: '$bookList'},
{$sort: { 'bookList.rank' : 1}},
{$skip:2},
{$limit:3},
{$group: {'_id': '$_id', bookList : {$push : '$bookList'}}}
]);
여기서 $push 배열의 필드의 값으로 투사합니다.
aggregate 안의 여러 json 형태로 들어간다는면 반드시 [] (중괄호를)넣어야 합니다.
이외도 다양한 제한자를 활용하여 논리적으로 원하는 값을 추출혹은 집계 조회할 수 있습니다.
물론 저장도 가능합니다.
핵심 포인트로
1. json형태를 고려하여 제한자를 사용할 것과
2. 제한자의 순서를 고려하여 쿼리를 짜야한다는 것입니다. (가령 array 안의 속성 값을 기준으로 정렬을 하고 싶다면
일단 $unwind를 활용하여 object를 전환하여 $sort를 진행하는 경우를 예로 들 수 있습니다.)
관련하여 조금 응용하여 위의 값을 활용한 쿼리를 공유하오니
참고하셔서 각자의 콜렉션의 db를 조회하는 데 유용하게 사용하시길 바랍니다.
db.test.aggregate([
{$match : { "neccessaryCode":"M","year":"2019","month":"7"}},
{$unwind: '$bookList'},
{$group: {'_id': '$_id', bookList : {$push : '$bookList'}}},
{$project: {"bookList":1, bookListCount: {$size: '$bookList'}}},
{$unwind: '$bookList'},
{$sort: {'bookList.loanCnt' :-1, 'bookList.rank' : 1}},
{'$skip': 0 },
{'$limit': 5 },
{$group: {'_id': '$_id' ,bookList : {$push : '$bookList'}, count :{$first : '$bookListCount'}}}
매치하고 풀어서 bookList로 array 값 푸시한 그룹
그다음 bookList 사이즈 값 구하고(size는 array로 묶인 것만 object는 카운트 안됨)
이어서 다시 풀어서 정렬하고 정렬한 값에서 skip과 limit를 구하여 이전에 구한 값과 다시 재 그룹화 하여 최종 값을 구하는 과정이다.
/* $project의 경우는 추출이며 이 경우에는 bookList의 값 하나를 활용하여 bookListCount 값을 $size 제한자를 활용하여 구하는 것입니다. */
감사합니다.
'IT > MongoDB' 카테고리의 다른 글
MONGODB - find (0) | 2020.06.13 |
---|---|
MONGODB - 기본구조 (0) | 2020.06.09 |
몽고DB 집계 함수 (0) | 2019.07.30 |
클라우드/빅데이터 (0) | 2019.07.27 |
MongoDB CRUD Operations(핵심) (0) | 2019.07.07 |