예제 실습을 위한 데이터 추가
db.orders.insertMany( [
{ _id: 0, name: "Pepperoni", size: "small", price: 19,
quantity: 10, date: ISODate( "2021-03-13T08:14:30Z" ) },
{ _id: 1, name: "Pepperoni", size: "medium", price: 20,
quantity: 20, date : ISODate( "2021-03-13T09:13:24Z" ) },
{ _id: 2, name: "Pepperoni", size: "large", price: 21,
quantity: 30, date : ISODate( "2021-03-17T09:22:12Z" ) },
{ _id: 3, name: "Cheese", size: "small", price: 12,
quantity: 15, date : ISODate( "2021-03-13T11:21:39.736Z" ) },
{ _id: 4, name: "Cheese", size: "medium", price: 13,
quantity:50, date : ISODate( "2022-01-12T21:23:13.331Z" ) },
{ _id: 5, name: "Cheese", size: "large", price: 14,
quantity: 10, date : ISODate( "2022-01-12T05:08:13Z" ) },
{ _id: 6, name: "Vegan", size: "small", price: 17,
quantity: 10, date : ISODate( "2021-01-13T05:08:13Z" ) },
{ _id: 7, name: "Vegan", size: "medium", price: 18,
quantity: 10, date : ISODate( "2021-01-13T05:10:13Z" ) }
])
size 가
medium
인 것들을 _id 가name
이되고, quantity 가totalQuantity
별칭으로 인 것으로 조회db.orders.aggregate([ { $match: { size: "medium" } }, { $group: { _id: { $getField : "name" }, totalQuantity: { $sum: { $getField : "quantity" } } } } ])
위 처럼 getField
를 매번 쓰기는 번거로우니 아래처럼 약어로 사용할 수도 있다
db.orders.aggregate([
{
$match: {
size: "medium"
}
},
{
$group: {
_id: "$name",
totalQuantity: {
$sum: "$quantity"
}
}
}
])
날짜별 매출, 평균 판매 수량을 조회
db.orders.aggregate([ // 날짜 기간 조회 { $match: { date: { $gte: new ISODate("2020-01-30"), $lt: new ISODate("2022-01-30") } } }, // group 처리 { $group: { _id: { $dateToString: { // dateToString - 날짜를 문자열로 변환해준다 format: "%Y-%m-%d", date: "$date" } }, totalOrderValue: { // totalOrderValue 라는 별칭을 줌 $sum: { // 필드를 곱할 때는 multiply 를 사용 $multiply: ["$price", "$quantity"] } }, averageOrderQuantity: { $avg: "$quantity" } } }, // stage 가 끝난 이후에는 별칭으로 정한 필드를 사용가능 // mysql 에서 as 로 컬럼조회 한 경우 group by 에서 사용 하는 케이스 // ex) select count(*) as `cnt` from test group by id having cnt > 0 { $sort: { totalOrderValue: -1 } } ])
예제 실습을 위한 데이터 추가
db.books.insertMany([
{ "_id" : 8751, "title" : "The Banquet", "author" : "Dante", "copies" : 2 },
{ "_id" : 8752, "title" : "Divine Comedy", "author" : "Dante", "copies" : 1 },
{ "_id" : 8645, "title" : "Eclogues", "author" : "Dante", "copies" : 2 },
{ "_id" : 7000, "title" : "The Odyssey", "author" : "Homer", "copies" : 10 },
{ "_id" : 7020, "title" : "Iliad", "author" : "Homer", "copies" : 10 }
])
조회한 값을 배열에 넣는 방법
db.books.aggregate([ { $group: { _id: "$author", books: { // push : 배열에 넣을 때 사용 $push : "$title" } }, } ])
document 자체를 넣는 방법
db.books.aggregate([ { $group: { _id: "$author", books: { // ROOT - 시스템 변수 이며 $$는 $ 이후에 나오는 것을 참조변수라고 생각하면됨 // ${$ROOT} - $ROOT 의 결과를 변수화 하여 데이터를 넣은 것 // ROOT는 top-level document 를 가리킴 $push : "$$ROOT" } }, } ])
4-1. group 안에서 별칭을 정의한 경우
db.books.aggregate([
{
$group: {
_id: "$author",
books: {
$push : "$$ROOT"
},
// group 안에 별칭을 정의한 경우
totalCopies: {
$sum: "$copies"
}
},
}
])
4-2. stage 로 꼭 분리해야하는 경우
db.books.aggregate([
{
$group: {
_id: "$author",
books: {
$push : "$$ROOT"
}
},
},
{
// addFields 를 사용하여 커스텀 필드를 추가
$addFields: {
totalCopies: { // totalCopies 별칭 정의
$sum: "$books.copies"
}
}
}
])
기존 orders 를 삭제 및 새로운 데이터 추가
db.orders.drop()
db.orders.insertMany([
{ "productId" : 1, "price" : 12, },
{ "productId" : 2, "price" : 20, },
{ "productId" : 3, "price" : 80, }
])
db.products.insertMany([
{ "id" : 1, "instock" : 120 },
{ "id" : 2, "instock" : 80 },
{ "id" : 3, "instock" : 60 },
{ "id" : 4, "instock" : 70 }
])
join 맛보기
db.orders.aggregate([ // mysql 의 join 함수명을 mql에서는 lookup 이라고 씀 { $lookup: { from: "products", // join 시킬 collection localField: "productId", // 주체의 key foreignField: "id", // join 시킬 fk as: "data" // 별칭 지정 } }, { $match: { // expr(expression) 같은 필드를 기준으로 비교를 할 때 사용 $expr: { // expr 를 사용할 때 비교값을 array 로 하면 제대로된 값이 나올수 없다 $gt: ['$data.instock', '$price'] } } } ])
5-1. unwind
사용하여 expr
사용 시 배열 사용할 수 있게 하기
unwind
는 묶었던 데이터를 다시 풀어서 사용해야할 때 쓴다
db.orders.aggregate([
{
$lookup: {
from: "products",
localField: "productId",
foreignField: "id",
as: "data"
}
},
{
$unwind: "$data"
},
{
$match: {
$expr: {
$gt: ['$data.instock', '$price']
}
}
}
])
sample
사용하여 일부만 조회하기
sample
은 랜덤하여 조회하기 때문에 limit 와는 다르다
db.listingsAndReviews.aggregate([
{
$sample: { size: 3 }
},
{
$project: {
name: 1,
summary: 1
}
}
])
skip
사용하기db.listingsAndReviews.aggregate([ { $match: { property_type: "Apartment" }, }, { $sort: { number_of_reviews: -1 } }, { // skip - offset 이라고 생각하면됨 $skip: 0 }, { $limit: 5 }, { $project: { name: 1, number_of_reviews: 1 } } ])
out
을 이용하여 조회 결과를 다른 collection 에 저장
db.books.aggregate([
{
$group: {
_id: "$author",
books: { $push: "$title" }
}
},
{
// authors 라는 collection 이 새로 만들어지면서 조회된 결과가 저장된다
$out: "authors"
}
])
'Database > Mongo' 카테고리의 다른 글
배열과 내장 document 를 다루는 방법 (Update) (0) | 2023.03.06 |
---|---|
배열과 내장 document 를 다루는 방법 (Read) (0) | 2023.03.06 |
유용한 Query 함수들 (0) | 2023.03.06 |
MongoDB - 기본 CRUD 예제 2 (0) | 2023.03.06 |
MongoDB - 기본 CRUD 예제 1 (0) | 2023.03.06 |