MongoDB
MongoDB 쿼리 작성법과 최적화
코샵
2024. 12. 3. 11:02
반응형
소개
MongoDB는 강력한 쿼리 기능을 제공하는 NoSQL 데이터베이스입니다. 이번 글에서는 MongoDB의 다양한 쿼리 작성법과 실전 활용 방법을 자세히 알아보겠습니다.
기본 CRUD 쿼리
데이터 조회 (Read)
// 기본 조회
db.users.find() // 모든 사용자 조회
db.users.findOne() // 첫 번째 사용자 조회
// 조건 조회
db.users.find({ age: 30 }) // 나이가 30인 사용자
db.users.find({ name: "John" }) // 이름이 John인 사용자
// 특정 필드만 조회
db.users.find(
{ age: 30 },
{ name: 1, email: 1, _id: 0 } // name과 email만 조회 (_id 제외)
)
데이터 생성 (Create)
// 단일 문서 삽입
db.users.insertOne({
name: "John Doe",
email: "john@example.com",
age: 30
})
// 다중 문서 삽입
db.users.insertMany([
{
name: "Jane Doe",
email: "jane@example.com",
age: 28
},
{
name: "Bob Smith",
email: "bob@example.com",
age: 35
}
])
데이터 수정 (Update)
// 단일 문서 수정
db.users.updateOne(
{ name: "John Doe" }, // 조건
{ $set: { age: 31 } } // 수정할 내용
)
// 다중 문서 수정
db.users.updateMany(
{ age: { $lt: 30 } }, // 30세 미만
{ $inc: { age: 1 } } // 나이 1 증가
)
// 문서 교체
db.users.replaceOne(
{ name: "John Doe" },
{
name: "John Smith",
email: "john.smith@example.com",
age: 31
}
)
데이터 삭제 (Delete)
// 단일 문서 삭제
db.users.deleteOne({ name: "John Doe" })
// 다중 문서 삭제
db.users.deleteMany({ age: { $lt: 25 } })
// 컬렉션 전체 삭제
db.users.deleteMany({})
고급 쿼리 연산자
비교 연산자
// $eq: 같음
db.users.find({ age: { $eq: 30 } })
// $ne: 같지 않음
db.users.find({ age: { $ne: 30 } })
// $gt, $gte: 초과, 이상
db.users.find({ age: { $gt: 30 } }) // 30 초과
db.users.find({ age: { $gte: 30 } }) // 30 이상
// $lt, $lte: 미만, 이하
db.users.find({ age: { $lt: 30 } }) // 30 미만
db.users.find({ age: { $lte: 30 } }) // 30 이하
// $in: 배열 안의 값과 일치
db.users.find({ age: { $in: [25, 30, 35] } })
// $nin: 배열 안의 값과 불일치
db.users.find({ age: { $nin: [25, 30, 35] } })
논리 연산자
// $and: 모든 조건 만족
db.users.find({
$and: [
{ age: { $gte: 25 } },
{ age: { $lte: 35 } }
]
})
// $or: 하나 이상의 조건 만족
db.users.find({
$or: [
{ age: { $lt: 25 } },
{ age: { $gt: 35 } }
]
})
// $not: 조건 불만족
db.users.find({
age: { $not: { $eq: 30 } }
})
// $nor: 모든 조건 불만족
db.users.find({
$nor: [
{ age: 25 },
{ name: "John" }
]
})
요소 연산자
// $exists: 필드 존재 여부
db.users.find({ email: { $exists: true } })
// $type: 필드 타입 검사
db.users.find({ age: { $type: "number" } })
배열 연산자
// $all: 모든 요소 포함
db.users.find({
interests: { $all: ["reading", "music"] }
})
// $elemMatch: 배열 요소 매칭
db.users.find({
scores: {
$elemMatch: {
$gt: 80,
$lt: 90
}
}
})
// $size: 배열 크기
db.users.find({
interests: { $size: 3 }
})
집계 파이프라인
기본 집계
// $match: 문서 필터링
db.users.aggregate([
{
$match: {
age: { $gte: 25 }
}
}
])
// $group: 그룹화
db.users.aggregate([
{
$group: {
_id: "$age",
count: { $sum: 1 },
avgScore: { $avg: "$score" }
}
}
])
// $sort: 정렬
db.users.aggregate([
{
$sort: {
age: -1, // 내림차순
name: 1 // 오름차순
}
}
])
고급 집계
// $lookup: 조인
db.orders.aggregate([
{
$lookup: {
from: "users",
localField: "userId",
foreignField: "_id",
as: "userInfo"
}
}
])
// $project: 필드 선택/변환
db.users.aggregate([
{
$project: {
fullName: {
$concat: ["$firstName", " ", "$lastName"]
},
age: 1,
_id: 0
}
}
])
// $unwind: 배열 풀기
db.users.aggregate([
{
$unwind: "$interests"
}
])
인덱스와 쿼리 최적화
인덱스 생성
// 단일 필드 인덱스
db.users.createIndex({ age: 1 })
// 복합 인덱스
db.users.createIndex(
{ age: 1, name: 1 }
)
// 유니크 인덱스
db.users.createIndex(
{ email: 1 },
{ unique: true }
)
쿼리 성능 분석
// 실행 계획 확인
db.users.find({ age: 30 }).explain()
// 쿼리 성능 통계
db.users.find({ age: 30 }).explain("executionStats")
실전 활용 예제
페이지네이션
// skip과 limit 사용
db.users.find()
.skip(20) // 처음 20개 건너뛰기
.limit(10) // 10개만 가져오기
텍스트 검색
// 텍스트 인덱스 생성
db.articles.createIndex({ content: "text" })
// 텍스트 검색
db.articles.find({
$text: {
$search: "mongodb database",
$caseSensitive: false
}
})
지리공간 쿼리
// 지리공간 인덱스 생성
db.places.createIndex({ location: "2dsphere" })
// 반경 내 검색
db.places.find({
location: {
$near: {
$geometry: {
type: "Point",
coordinates: [127.0, 37.5] // 경도, 위도
},
$maxDistance: 1000 // 미터 단위
}
}
})
마치며
MongoDB의 쿼리는 매우 유연하고 강력합니다. 기본적인 CRUD 연산부터 복잡한 집계 파이프라인까지, 상황에 맞는 적절한 쿼리를 작성할 수 있습니다. 성능 최적화를 위해서는 인덱스를 적절히 활용하고, 실행 계획을 분석하는 것이 중요합니다.