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에서 제공해주고 있는데, 잘 쓰지 못하고 있다...

노력하자.

참고 자료

Posted by lahuman