#집계 프레임워크
-파이프라인의 각 단계에서의 출력이 다음 단계로의 입력으로 제공되는 파이프라인(집계 파이프라인,aggregation pipeline)을 정의한다.
$project - 출력 도큐먼트상에 배치할 필드를 지정한다.(projected)
$match - 처리될 도큐먼트를 선택하는 것. find()와 비슷한 역할을 수행한다.
$limit - 다음 단계에 전달될 도큐먼트의 수를 제한한다.
$skip - 지정된 수의 도큐먼트를 건너뛴다.
$unwind -배열을 확장하여 각 배열 항목에 대해 하나의 출력 도큐먼트를 생성한다.
$group -지정된 키로 도큐먼트를 그룹화한다.
$sort -도큐먼트를 정렬한다.
$geoNear - 지리 공간위치 근처의 도큐먼트를 선택한다.
$out - 파이프라인의 결과(출력)를 컬렉션에 쓴다.
$redact -특정 데이터에 대한 접근을 제어한다.
ex)
db.컬렉션이름.aggregate([ {$match: ...}, {$group: ...}, {$sort: ...} ] )
1)전체 제품 컬렉션은 $match 작업으로 전달되고, 입력된 컬렉션으로부터 오직 특정 도큐먼트만 선택한다.
2)$match의 출력은 $group 연산자로 전달되며, $group 연산자는 출력을 특정 키로 그룹화하여 합계 및 평균과 같은 새로운 정보를 제공한다.
3)$group 연산자의 출력은 마지막 단계인 $sort 연산자로 전달되어 정렬이 수행되고 그 뒤에 최종 결과로 반환된다.
SQL vs 집계 프레임워크 비교
SQL 명령어 | 집계 프레임워크 연산자 |
SELECT | $project $group 함수 : $sum,$min,$avg 등 |
FROM | db.collectionName.aggregate(. . .) |
JOIN | $unwind |
WHERE | $match |
GROUP BY | $group |
HAVING | $match |
$project- 처리할 도큐먼트의 필드를 지정한다.
ex)
db.uesrs.findOne(
{username: 'kbanker',
hashed_password: 'bd1cfa194c3a603e7186780824b04419'},
{first_name:1, last_name:1} //이름과 성을 반환하는 프로젝션 개체
)
db.uesrs.aggregate([
{$match: {username: 'kbanker',
hashed_password: 'bd1cfa194c3a603e7186780824b04419'},
{$project: {first_name:1, last_name:1}} //이름과 성을 반환하는 프로젝트 파이프라인 연산자
])
-많은 수의 도큐먼트 재형성(reshaping)기능을 사용할 수 있다.
$group- 지정된 키별로 도큐먼트를 그룹화한다.
-$group 연산자에 _id필드를 정의하여 도큐먼트를 그룹화하는 방법이 있다. $group 연산자는 입력된 도큐먼트를 지정된 _id 필드로 그룹화하여 각 도큐먼트 그룹에 대한 집계된 정보를 제공한다.
ex)
db.orders.aggregate([
{$match: {purchase_data: {$gte: new Date(2010, 0 , 1}}},
{$group: {
_id: {year : {$year : '$purchase_date'},
month: {$month : '$purchase_date'}},
count: {$sum: 1},
total: {$sum: '$sub_total'}}},
{$sort: {_id:-1}}
]);
result
{"_id : {"year" : 2014, "month" : 11},
"count" : 1, "total" : 4897}
{"_id : {"year" : 2014, "month : 8},
"count" : 2, "total" : 11093 }
...
-그룹의 _id 필드를 정의할 때 하나 이상의 기존 필드를 사용하거나 도큐먼트 재형성 기능 중 하나를 사용할 수 있다.
(이 예제는 $year,$month 재형성 함수의 활용을 보여준다.)
$group 함수 | |
$addToSet | 그룹에 고유한 값의 배열을 만든다 |
$first | 그룹의 첫 번째 값. $sort를 선행해야만 의미가 있다. |
$last | 그룹의 마지막 값. $sort를 선행해야만 의미가 있다. |
$max | 그룹의 필드 최댓값 |
$min | 그룹의 필드 최솟값 |
$avg | 필드의 평균값 |
$sum | 그룹의 모든 값의 배열을 반환한다. 중복값을 제거하지 않는다. |
$sum | 그룹의 모든 값의 합계 |
$match, $sort, $skip, $limit- 선택하고, 정렬하며, 건너뛰고,크기를 제한한다.
ex)
page_number = 1
product = db.products.findOne({'slug': '~~'})
reviews = db.reviews.find({'product_id': product['_id']}).
skip((page_number - 1) * 12).
limit(12).
sort({'helpful_votes': -1})
집계 프레임워크에서의 동일한 쿼리
reviews2 = db.reviews.aggregate([
{$match: {'product_id': product['_id']}}},
{$skip : (page_number - 1) * 12},
{$limit: 12},
{$sort: {'helpful_votes': -1}}
]).toArray();
$unwind -배열의 모든 항목에 대해 하나의 출력 도큐먼트를 생성하여 배열을 확장
ex)
db.products.findOne({},{category_ids:1})
{
"_id" : ObjectId("~~"),
"category_ids" : [
ObjectId("~~"),
ObjectId("~~")
]
}
db. productts.aggregate([
{$project : {category_ids:1}},
{$unwind : '$category_ids'},
{$limit : 2}
]);
result
{ "_id" : ObjectId("~~"),
"category_ids" : ObjectId("~~48") }
{ "_id" : ObjectId("~~"),
"category_ids" : ObjectId("~~49") }
$out - 파이프라인의 결과를 컬렉션에 기록한다
db.orders.aggregate([
{$match: upperManhattanOrders},
{$group: sumByUserId},
{$match: orderTotalLarge},
{$sort: sortTotalDesc},
{$out: 'targetedCustomers'}
]);
#도큐먼트 재구성(reshape)
ex)
first 와 last name을 name이라는 하위객체를 만들어서 사용
db.users.aggregate([
{$match: {username: 'kbanker'}},
{$project: {name: {first:'$first_name',
last:'$last_name'}}
}
])
->
{ "_id" : ObjectId("~~"),
"name" : {"first" : "kyle",
"last" : "banker"}
}
문자열 함수
문자열 | |
$concat | 두 개 이상의 문자열을 단일 문자열로 연결한다 |
$strcasecmp | 대/소문자를 구분하지 않는 문자열 비교를 하며,숫자를 반환한다 |
$substrBytes | 문자열의 부분 문자열을 만든다 |
$toLower | 문자열을 모두 소문자로 변환한다 |
$toUpper | 문자열을 모두 대문자로 변환한다 |
산술 함수
산술 | |
$add | 배열 번호를 추가한다 |
$divide | 첫 번째 숫자를 두 번째 숫자로 나눈다 |
$mod | 첫 번째 숫자의 나머지를 두 번째 숫자로 나눈다 |
$multiply | 숫자 배열을 곱한다 |
$subtract | 첫 번째 숫자에서 두 번째 숫자를 뺀다 |
날짜/시간 함수
날짜/시간 | |
$dayOfYear | 연 중의 일로서 1에서 366까지다 |
$dayOfMonth | 월 중의 일로서 1에서 31까지다 |
$dayOfWeek | 주 중의 일로서 1에서 7까지이며,1은 일요일을 의미한다 |
$year | 날짜의 연 부분이다 |
$month | 날짜의 월 부분으로 1에서 12까지다 |
$week | 연 중의 주 로서, 0에서 53까지다 |
$hour | 시간을 뜻하고, 0에서 23까지다 |
$minute | 분을 뜻하고, 0에서 59까지다 |
$second | 초를 뜻하고, 0에서 59까지다(윤초는 60초) |
$millisecond | 시간 중 밀리초를 뜻하며, 0에서 999까지다 |
논리 함수
논리 | |
$and | 배열 내의 모든 값이 true의 경우는 true |
$cmp | 두 개 값을 비교하여 결괏값을 반환해 주며, 두 값이 동일하면 0을 반환한다 |
$cond | if...then...else 조건부 논리 x?y: z 삼항연산자와 유사 |
$eq | 두 값이 동일한지의 여부 확인 |
$gt | 하나의 값이 다른 하나의 값보다 큰지의 여부 확인 |
$gte | 하나의 값이 다른 하나의 값보다 크거나 같은지의 여부 확인 |
$ifNull | null값/표현식을 지정된 값으로 변환한다 |
$lt | 하나의 값이 다른 하나의 값보다 작은지의 여부 확인 |
$lte | 하나의 값이 다른 하나의 값보다 작거나 같은지의 여부 확인 |
$ne | 두 값이 동일하지 않은지에 대한 여부 확인 |
$not | 주어진 값의 반대 조건을 반환한다. 값이 true면 false, flase이면 true |
$or | 배열의 값 중 그 어떤 하나라도 ture인 경우 true |
집합 함수
집합 | |
$setEquals | 두 개의 집합이 완전히 같은 요소를 가지는 경우 true |
$setIntersection | 두 개의 집합에서 공통적으로 존재하는 요소의 배열을 반환한다 |
$setDifference | 두 번째 집합에 없는 첫 번째 집합의 요소를 반환한다 |
$setUnion | 두 집합의 합집합을 반환한다 |
$setIsSubset | 두 번째 집합이 첫 번째 집합의 부분집합이면 true (두 번째 집합의 모든 요소도 첫 번째 집합의 부분집합) |
$anyElementTrue | 집합의 요소 중 그 어느 하나라도 true이면 true |
$allElementTrue | 집합의 모든 요소가 true일 경우에만 true |
$not | 주어진 값의 반대 조건을 반환한다.값이 true이면 false,flase이면 true |
$or | 배열의 값 중 그 어떤 하나라도 true인 경우는 true |
기타 함수
기타 | |
$meta | 텍스트 검색 관련 정보에 접근한다. |
$size | 배열의 크기를 반환한다 |
$map | 배열의 각 멤버에 표현식(expression)을 적용한다 |
$let | 표현식의 범위 내에서 사용되는 변수를 정의한다 |
$literal | 표현식의 값을 평가하지 않고 반환한다 |
'DataBase > NoSQL' 카테고리의 다른 글
[NoSQL] MongoDB cluster 구성 정리 (feat production, NCP) (0) | 2024.02.26 |
---|---|
[NoSQL] Docker로 EC2에 MongoDB 설치해서 NoSQL booster for mongodb에 연결하기 (0) | 2024.02.25 |
[NoSQL] MongoDB 쿼리 언어 총정리2 (0) | 2021.01.20 |
[NoSQL] MongoDB 쿼리 언어 총정리1 (1) | 2021.01.20 |
[NoSQL] MongoDB Index 생성,예제,효율확인 (0) | 2021.01.19 |
댓글