더미 데이터 넣기
use('cosdb');
for(let i=1; i < 21; i++) {
db.users.insertOne({"i" : i, "username" : "user" + i, "age" : 12});
}
db.users.find();
SELECT 연습을 할 건데
기본적인 CRUD는 스프링 부트에서 지원해주지만
복잡한 쿼리(고급 SELECT)를 수행하기 위해서는 쿼리를 직접 짜야한다.
이때 aggregate(집계 함수)를 사용해준다.
집계 함수의 포인트 : 파이프 라인
SELECT 한 결과를 가지고 다시 SELECT를 거치며 내가 원하는 결과를 도출할 수 있다.
몽고에서 파이프 라인을 도큐먼트 스트림이라고 부른다
1. match 일치 (RDB : WHERE) : 행을 추리기
2. projection 선출 : 컬럼 추리기
3. sort 정렬 (RDB : ORDER BY) : 정렬
4. skip 건너뛰기
5. limit 제한
1번부터 5번을 거치며 도큐먼트를 넘겨준다.
그래서 도큐먼트 스트림인 것이다.
도큐먼트는 RDB에서 하나의 row를 말한다!
1. match
db.users.find({i:1});
find 한 결과와 똑같은 결과를 aggregate를 통해 뽑아보자.
aggregate를 사용할 때는 무조건 배열을 넣어준다.
match가 들어갈 수 있고 projection이 들어갈 수 있고
여러 개가 들어갈 수 있으니까!
db.users가 FROM으로 데이터베이스를 끌어올린 것이다.
match 안에 중괄호가 RDB의 WHERE 절이다.
db.users.aggregate([{$match:{i:1}}]);
2. projection
출력된 결과 중에 필드를 걸러보자.
projection에서 1의 의미는 true이다.
_id는 디폴트로 항상 나온다.
이게 보고 싶지 않다면 _id : 0을 강제로 넣어줘야 한다.
db.users.aggregate([{$match:{i:1}}, {$project:{_id:0, i:1, username:1}}]);
3. limit
age가 12인 것을 모두 출력해보니 행이 걸러지지 않았다.
이 상황에서 projection 하는 거보다 먼저 limit을 사용해 행을 줄인 뒤 컬럼을 줄이는 게 효율적인 쿼리겠다.
db.users.aggregate([{$match:{age:12}}, {$limit:5}, {$project:{_id:0, i:1, username:1}}]);
4. sort
내가 키 순서로 정렬하고 싶으면 sort를 먼저 한 뒤에 limit을 걸어야겠다.
어떤 걸 먼저 실행할지의 순서는 상황마다 다르다.
정렬 ASC와 DESC는 1과 -1로 구분한다.
-1은 내림차순
db.users.aggregate([{$match:{age:12}}, {$sort:{username:-1}}, {$limit:5}, {$project:{_id:0, i:1, username:1}}]);
1은 오름차순
db.users.aggregate([{$match:{age:12}}, {$sort:{username:1}}, {$limit:5}, {$project:{_id:0, i:1, username:1}}]);
limit을 먼저 한 뒤에 sort를 수행하면 또 다른 결과가 나온다.
1 오름차순
db.users.aggregate([{$match:{age:12}}, {$limit:5}, {$sort:{username:1}}, {$project:{_id:0, i:1, username:1}}]);
-1 내림차순
db.users.aggregate([{$match:{age:12}}, {$limit:5}, {$sort:{username:-1}}, {$project:{_id:0, i:1, username:1}}]);
5. skip
skip은 step의 개념이 아니라 "앞에 50개 스킵하고 안 보겠다" 이런 의미이다.
skip의 위치도 상황에 따라 다르다.
skip을 걸고 limit을 걸면 1, 2, 3을 스킵하고 4, 5, 6, 7, 8 데이터가 나오고
db.users.aggregate([{$match:{age:12}}, {$skip:3}, {$limit:5}, {$sort:{username:1}}, {$project:{_id:0, i:1, username:1}}]);
limit을 걸고 skip을 걸면 2개 데이터만 나올 것이다.
db.users.aggregate([{$match:{age:12}}, {$limit:5}, {$skip:3}, {$sort:{username:1}}, {$project:{_id:0, i:1, username:1}}]);
[출처]
https://cafe.naver.com/metacoding
메타 코딩 유튜브
https://www.youtube.com/c/%EB%A9%94%ED%83%80%EC%BD%94%EB%94%A9