MongoDB aggregate 사용
다음과 같은 형식의 여러 ROW의 데이터를 하나의 데이터로 표현 하고 싶었다.
# DATA
{
"_id" : ObjectId("5c864b1e1cd4038eed5b5633"),
"link_tag" : [
"#핫앤쿨",
"#마스크팩",
"#홈케어",
"#리뉴메디",
"#젊줌마",
"#예뻐지는시간"
],
"name" : "홈케어",
"text" : "젊어지는시간\n. .\n\n#핫앤쿨 #마스크팩 #홈케어\n#리뉴메디 #젊줌마 #예뻐지는시간",
"owner" : "10961953345",
"shortcode" : "Bu3eX2iHIFG",
"display_url" : "https://scontent-icn1-1.cdninstagram.com/vp/c330b55401b96aca266acca202386b42/5D08D97D/t51.2885-15/e35/54446467_181108306201409_5180562059450456961_n.jpg?_nc_ht=scontent-icn1-1.cdninstagram.com",
"is_video" : false,
"accessibility_caption" : "Image may contain: 1 person",
"writed_date" : ISODate("2019-03-11T11:44:00.000Z"),
"hash" : "086e2b6a65b823c887ef1afc19734f67",
"createdAt" : ISODate("2019-03-11T11:48:46.276Z"),
"updatedAt" : ISODate("2019-03-11T12:22:43.532Z"),
"__v" : 3
}
/* 2 */
{
"_id" : ObjectId("5c864b1e1cd4038eed5b5632"),
"link_tag" : [
"#토니슈어",
"#다낭까지와서",
"#이러고있다",
"#간절한걸어떡함",
"#플라즈마",
"#갈바닉",
"#너네둘만믿는다",
"#동안피부",
"#얼굴마사지기",
"#피부개선",
"#탄력",
"#피부미용기기",
"#미용",
"#홈케어",
"#피부미인",
"#데일리",
"#뷰티",
"#살균",
"#셀프",
"#피부질환",
"#플라즈마",
"#트러블케어",
"#피부",
"#피부과",
"#선물",
"#물광피부",
"#보습",
"#안티에이징",
"#led마스크",
"#미백",
"#콜라겐"
],
"name" : "홈케어",
"text" : "토니느님~ 제 피부를 10년전으로 돌려주세요\n\n제발요....♡ .\n\n#토니슈어 #다낭까지와서 #이러고있다 #간절한걸어떡함 #플라즈마 #갈바닉 #너네둘만믿는다 #동안피부 가즈앙~ \n#얼굴마사지기 #피부개선 #탄력 #피부미용기기 #미용 #홈케어 #피부미인 #데일리 #뷰티 #살균 #셀프 #피부질환 #플라즈마 #트러블케어 #피부 #피부과 #선물 #물광피부 #보습 #안티에이징 #led마스크 #미백 #콜라겐",
"owner" : "10698447319",
"shortcode" : "Bu3e2n_jrrE",
"display_url" : "https://scontent-icn1-1.cdninstagram.com/vp/97d840dbdea55753d2a976302f90002b/5D065CE9/t51.2885-15/fr/e15/s1080x1080/53176269_319394038719034_3474616797099883761_n.jpg?_nc_ht=scontent-icn1-1.cdninstagram.com",
"is_video" : false,
"accessibility_caption" : "Image may contain: outdoor and water",
"writed_date" : ISODate("2019-03-11T11:48:12.000Z"),
"hash" : "c9a418d8295391c1c83553f0316d1127",
"createdAt" : ISODate("2019-03-11T11:48:46.266Z"),
"updatedAt" : ISODate("2019-03-11T12:22:43.527Z"),
"__v" : 3
}
원하는 결과 데이터
[
{ "tag" : "#미백", "count" : 3},
{ "tag" : "#물광", "count" : 4},
{ "tag" : "#보습", "count" : 10},
...
]
구글을 검색하니 $push명령어를 찾았다.
내가 처리한 Query는 다음과 같다.
db.hashtag.aggregate([
{ $match: { $and: [{ name: "테그명" }, { "createdAt": { $gte: (new Date()), $lt: (new Date()) } }] } },
{$unwind: "$link_tag"},
{$group:{_id:null, clrs: {$push: {name: "$link_tag", count:1}}}},
{$unwind: "$clrs"},
{$group:{_id:"$clrs.name", size: {$sum:"$clrs.count"}}},
{ $sort: { size:-1} },
{ $limit : 5 },
{$project: {_id:1, size:1 }
]);
이렇게 처리 하면 다음과 같은 결과를 받을 수 있다.
[
{ _id:"#물광", size:15 },
{ _id:"#홈케어", size:13 }
{ _id:"#대일리", size:12 }
]
다음은 매 시간별로 수집된 데이터를 counting 하는 query 이다. 내가 원하는 결과는 다음과 같다.
[
{"date": "2018-03-14 10", "count":30},
{"date": "2018-03-14 11", "count":20},
{"date": "2018-03-14 12", "count":33},
{"date": "2018-03-14 13", "count":34}
]
다행이 이번 QUERY는 한방에 처리 하였다.
db.hashtag.aggregate([
{ $match: { $and: [{ name: "태그명" }, { "createdAt": { $gte: (new Date()), $lt: (new Date()) } }] } },
{
$group:
{
_id:
{
hour: { $hour: "$createdAt" },
day: { $dayOfMonth: "$createdAt" },
month: { $month: "$createdAt" },
year: { $year: "$createdAt" }
},
value: { $sum: 1 },
date: { $first: "$createdAt" },
sortDate: { $first: "$createdAt" }
}
},
{
$project:
{
date:
{
$dateToString: { format: "%Y-%m-%d %H", date: "$date" }
},
sortDate: 1,
value: 1,
_id: 0
}
},
{ $sort: { sortDate: 1 }}
])
분명히 많은 기능을 Mongodb에서 제공해주고 있는데, 잘 쓰지 못하고 있다…