본문으로 바로가기

1. $group

sql 구문의 GROUP BY와 유사한 역할을 수행하게 한다고 할 수 있다.

1) 기본 형태

{
  $group:
    {
      _id: <expression>, // Group By Expression
      <field1>: { <accumulator1> : <expression1> },
      ...
    }
 }

accumulator에 필요한 연산을 활용하면 특정 필드에 연산을 수행한 값이 들어가게하고 그룹화 할 수 있습니다.

2) 연산 종류

$addToSet 각 그룹의 고유한 값만 담은 배열을 반환
$avg 숫자 값의 평균을 반환, 숫자가 아닌 값을 무시
$first 각 그룹의 첫 번째 문서에서 값을 반환
$last 각 그룹의 마지막 문서에서 값을 반환 
$max 각 그룹의 최고 값을 반환
$mergeObjects 각 그룹에 대한 문서를 결합하여 반환
$min 각 그룹의 최저 값을 반환
$push 각 그룹의 표현식 값 배열을 반환
$stdDevPop 입력 값의 모집단 표준 편차를 반환
$stdDevSamp 입력 값의 샘플 표준 편차를 반환
$sum 숫자 값의 합을 반환, 숫자가 아닌 값을 무시

3) 예시

sales라는 컬렉션을 생성하고

db.sales.insertMany([
  { "_id" : 1, "item" : "abc", "price" : NumberDecimal("10"), "quantity" : NumberInt("2"), "date" : ISODate("2014-03-01T08:00:00Z") },
  { "_id" : 2, "item" : "jkl", "price" : NumberDecimal("20"), "quantity" : NumberInt("1"), "date" : ISODate("2014-03-01T09:00:00Z") },
  { "_id" : 3, "item" : "xyz", "price" : NumberDecimal("5"), "quantity" : NumberInt( "10"), "date" : ISODate("2014-03-15T09:00:00Z") },
  { "_id" : 4, "item" : "xyz", "price" : NumberDecimal("5"), "quantity" :  NumberInt("20") , "date" : ISODate("2014-04-04T11:21:39.736Z") },
  { "_id" : 5, "item" : "abc", "price" : NumberDecimal("10"), "quantity" : NumberInt("10") , "date" : ISODate("2014-04-04T21:23:13.331Z") },
  { "_id" : 6, "item" : "def", "price" : NumberDecimal("7.5"), "quantity": NumberInt("5" ) , "date" : ISODate("2015-06-04T05:08:13Z") },
  { "_id" : 7, "item" : "def", "price" : NumberDecimal("7.5"), "quantity": NumberInt("10") , "date" : ISODate("2015-09-10T08:43:00Z") },
  { "_id" : 8, "item" : "abc", "price" : NumberDecimal("10"), "quantity" : NumberInt("5" ) , "date" : ISODate("2016-02-06T20:20:13Z") },
])

sales 컬렉션 안의 도큐먼트 개수를 반환하게 한다면, 아래와 같이 명령할 수 있다.

db.sales.aggregate( [
  {
    $group: {
       _id: null,
       count: { $sum: 1 }
    }
  }
] )

아래와 같은 결과가 나온다.

{ "_id" : null, "count" : 8 }

sql 구문으로 본다면, 아래와 같다.

SELECT COUNT(*) AS count FROM sales

좀 더 복잡한 예시로

item 필드와 전체판매양(totalSaleAmount)에 대한 값을 그룹핑한 후 totalSaleAmount이 100 이상인 경우에 대해서만 출력하게 한다면,

아래와 같이 표현할 수 있다.

db.sales.aggregate(
  [
    // First Stage
    {
      $group :
        {
          _id : "$item",
          totalSaleAmount: { $sum: { $multiply: [ "$price", "$quantity" ] } }
        }
     },
     // Second Stage
     {
       $match: { "totalSaleAmount": { $gte: 100 } }
     }
   ]
 )

아래와 같은 결과를 출력하게 된다.

{ "_id" : "abc", "totalSaleAmount" : NumberDecimal("170") }
{ "_id" : "xyz", "totalSaleAmount" : NumberDecimal("150") }
{ "_id" : "def", "totalSaleAmount" : NumberDecimal("112.5") }

sql 구문으로 생각해본다면 아래와 같이 나타낼 수 있다.

SELECT item,
   Sum(( price * quantity )) AS totalSaleAmount
FROM   sales
GROUP  BY item
HAVING totalSaleAmount >= 100

2. $match

위의 group 예시에서도 사용되었듯이 $match는 특정 조건에 일치하는 값만 반환하도록 할 때 사용한다.

1) 기본 형태

{ $match: { <query> } }

2) 예시

아래와 같이 articles 컬렉션을 생성했을 때

{ "_id" : ObjectId("512bc95fe835e68f199c8686"), "author" : "dave", "score" : 80, "views" : 100 }
{ "_id" : ObjectId("512bc962e835e68f199c8687"), "author" : "dave", "score" : 85, "views" : 521 }
{ "_id" : ObjectId("55f5a192d4bede9ac365b257"), "author" : "ahn", "score" : 60, "views" : 1000 }
{ "_id" : ObjectId("55f5a192d4bede9ac365b258"), "author" : "li", "score" : 55, "views" : 5000 }
{ "_id" : ObjectId("55f5a1d3d4bede9ac365b259"), "author" : "annT", "score" : 60, "views" : 50 }
{ "_id" : ObjectId("55f5a1d3d4bede9ac365b25a"), "author" : "li", "score" : 94, "views" : 999 }
{ "_id" : ObjectId("55f5a1d3d4bede9ac365b25b"), "author" : "ty", "score" : 95, "views" : 1000 }

author이 dave인 도큐먼트만 출력한다면 아래와 같이 명령할 수 있다.

db.articles.aggregate(
    [ { $match : { author : "dave" } } ]
);

아래와 같이 결과를 반환하게 된다.

{ "_id" : ObjectId("512bc95fe835e68f199c8686"), "author" : "dave", "score" : 80, "views" : 100 }
{ "_id" : ObjectId("512bc962e835e68f199c8687"), "author" : "dave", "score" : 85, "views" : 521 }

 

3. $sort

정렬을 위해 사용한다.

1) 기본 형태

{ $sort: { <field1>: <sort order>, <field2>: <sort order> ... } }

정렬을 원하는 필드에 대한 오름차순이라면 1, 내림차순이라면 -1이라고 지정해주면 된다.

2) 예시

간단하게 아래 같은 형태로 활용할 수 있다.

db.users.aggregate(
   [
     { $sort : { age : -1, posts: 1 } }
   ]
)

 

 


모든 내용 출처는 공식문서입니다.

 

Aggregation Pipeline Stages — MongoDB Manual

Reference > Operators > Aggregation Pipeline Stages Aggregation Pipeline Stages In the db.collection.aggregate method and db.aggregate method, pipeline stages appear in an array. Documents pass through the stages in sequence. Stages db.collection.aggregate

docs.mongodb.com


'DB > MongoDB' 카테고리의 다른 글

[MongoDB] Aggregate Pipeline 사용 ( $project / $limit )  (0) 2020.04.29
[MongoDB] aggregation란?  (0) 2020.04.29
[MongoDB] Mongoose란?  (0) 2020.03.19
[MongoDB] CRUD 작업하기  (0) 2020.03.19
[MongoDB] 몽고디비 시작하기  (0) 2020.03.18