배열 전개 표현식
use("cosdb");
var persons1 = {
_id: 1,
username : "ssar",
posts : [
{id:1, title:"제목1", content:"내용1"},
{id:2, title:"제목2", content:"내용2"},
{id:3, title:"제목3", content:"내용3"},
]
}
var persons2 = {
_id: 2,
username : "cos",
posts : [
{id:1, title:"제목1", content:"내용1"},
{id:2, title:"제목2", content:"내용2"},
{id:3, title:"제목3", content:"내용3"},
]
}
db.persons.insertOne(persons1);
db.persons.insertOne(persons2);
persons안에 posts 배열을 다룰 것이기 때문에 배열 표현식이다.
오브젝트 아이디를 사용하지 않기 위해 강제로 _id에 값을 넣어줬다.
unwind는 배열 전개 표현식이다.
얘를 사용하면 와인딩이된다. 크게 많이 쓸 일은 없다.
안에 있는 배열의 요소들이 빠져나오고 person의 필드 데이터는 중복되어 저장된다.
db.persons.aggregate(
[
{$match:{_id:1}},
{$unwind:"$posts"}
]
);
$project는 가짜 컬럼을 만들어낼 수 있다.
완전 다른형태의 도큐먼트를 만들어 낼 수 있는 것이다.
여기 postId, title, content는 가짜 컬럼이다.
여기 앞에 $가 참조하는 연산자이기 때문에 붙여놓았다.
데이터를 찾을 때 $를 붙이는 게 몽고의 문법이다.
db.persons.aggregate(
[
{$match:{_id:1}},
{$unwind:"$posts"},
{$project:{
_id:0,
username:1,
postId: "$posts.id",
title: "$posts.title",
content: "$posts.content"
}}
]
);
배열 필터 표현식
고급 select를 배워보자.
persons안에 posts의 아이디가 1인 도큐먼트가 보고 싶다.
이때 filter를 사용한다.
$filter를 쓸 때는 3가지 키 값이 있는데 바꿀 수 있는 게 아니다.
1. input : 여기 어떤 배열을 뭐 넣을 거야? (대상)
2. as : 별칭 (필수는 아님) input의 대상에게 별칭을 지어준다
3. cond(condition) : 조건식
operator | 설명 |
$eq | (equals) 주어진 값과 일치하는 값 |
$gt | (greater than) 주어진 값보다 큰 값 |
$gte | (greater than or equals) 주어진 값보다 크거나 같은 값 |
$lt | (less than) 주어진 값보다 작은 값 |
$lte | (less than or equals) 주어진 값보다 작거나 같은 값 |
$ne | (not equals) 주어진 값과 일치하지 않는 값 |
$in | (in) 주어진 배열 안에 속하는 값 |
$nin | (not in) 주어진 배열 안에 속하지 않는 값 |
별칭을 사용했다면 $를 2개($$)를 사용해서 데이터를 찾아낸다.
$를 하나만 적으면 도큐먼트 필드에서 찾고 있기 때문이다.
posts.id가 max인 것을 찾아서 같은 것만 찾아내 보자.
db.persons.aggregate(
[
{$match:{}}, // 그냥 중괄호를 걸면 전체검색
{$project:{
_id:0,
username:1,
new: {
$filter:{
input: "$posts",
as: "p",
cond: {$eq: ["$$p.id", {$max: "$posts.id"}]}
}
}
}}
]
);
post의 title이 "제목3"인 것
db.persons.aggregate(
[
{$match:{}}, // 그냥 중괄호를 걸면 전체검색
{$project:{
_id:0,
username:1,
new: {
$filter:{
input: "$posts",
as: "p",
cond: {$eq: ["$$p.title", "제목3"]}
}
}
}}
]
);
post의 id가 가장 큰 것만 출력
db.persons.aggregate([
{$match: {}},
{$project: {
_id:0,
username:1,
maxPostId: {$max: "$posts.id"}
}}
]);
post의 id가 1보다 큰 것들만 출력
db.persons.aggregate([
{$match: {}},
{$project: {
_id:0,
username:1,
new: {
$filter: {
input: "$posts",
as: "p",
cond: {$gt: ["$$p.id", 1]}
}
}
}}
]);
[출처]
https://cafe.naver.com/metacoding
메타 코딩 유튜브
https://www.youtube.com/c/%EB%A9%94%ED%83%80%EC%BD%94%EB%94%A9