📌 개념 정리
이 포스팅에서는 MongoDB를 활용한 데이터 삽입, 조회, 업데이트 및 집계(aggregation)에 대한 여러 문제를 다룹니다. 예제 코드와 함께 MongoDB의 기본적인 사용법을 익히고, 실용적인 쿼리를 통해 데이터베이스 관리 기술을 향상시킬 수 있습니다.
🚦 동작 원리 및 구조
- MongoDB 연결
- MongoClient를 사용하여 로컬 MongoDB 서버에 연결합니다.
- 데이터베이스와 컬렉션을 선택하여 작업을 진행합니다.
- 데이터 삽입
- insert_many를 사용하여 여러 문서를 한 번에 삽입할 수 있습니다.
- 데이터 조회
- find와 aggregate 메서드를 사용하여 조건에 맞는 데이터를 조회하고, 집계할 수 있습니다.
- 데이터 업데이트
- update_many 메서드를 사용하여 조건에 맞는 데이터를 일괄 수정할 수 있습니다.
💻 코드 예시 및 흐름 분석
- 데이터 삽입
- 먼저 MongoDB에 접속하여 books, movies, user_actions 컬렉션에 데이터를 삽입하는 코드입니다. 이 과정은 insert_data() 함수에서 수행됩니다.
- 삽입된 데이터는 나중에 다양한 쿼리를 통해 조회 및 분석할 수 있습니다.
from pymongo import MongoClient
from datetime import datetime
def insert_data():
client = MongoClient('mongodb://localhost:27017/')
db = client.local # 'local' 데이터베이스 사용
# 책 데이터 삽입
books = [
{"title": "Kafka on the Shore", "author": "Haruki Murakami", "year": 2002},
{"title": "Norwegian Wood", "author": "Haruki Murakami", "year": 1987},
{"title": "1Q84", "author": "Haruki Murakami", "year": 2009}
]
db.books.insert_many(books)
# 영화 데이터 삽입
movies = [
{"title": "Inception", "director": "Christopher Nolan", "year": 2010, "rating": 8.8},
{"title": "Interstellar", "director": "Christopher Nolan", "year": 2014, "rating": 8.6},
{"title": "The Dark Knight", "director": "Christopher Nolan", "year": 2008, "rating": 9.0}
]
db.movies.insert_many(movies)
# 사용자 행동 데이터 삽입
user_actions = [
{"user_id": 1, "action": "click", "timestamp": datetime(2023, 4, 12, 8, 0)},
{"user_id": 1, "action": "view", "timestamp": datetime(2023, 4, 12, 9, 0)},
{"user_id": 2, "action": "purchase", "timestamp": datetime(2023, 4, 12, 10, 0)},
]
db.user_actions.insert_many(user_actions)
print("Data inserted successfully")
client.close()
if __name__ == "__main__":
insert_data()
- 장르 추가
- 기존의 책 데이터에 "genre": "fantasy" 필드를 추가하는 코드입니다.
from pymongo import MongoClient
client = MongoClient('mongodb://localhost:27017/')
db = client.local
# 장르 추가
db.books.update_many(
{},
{"$set": {"genre": "fantasy"}}
)
print("Genre field added to all books")
client.close()
- 문제 해결 예시
- 문제 1: 특정 장르의 책 찾기
-
- 문제 설명: 데이터베이스에 새로운 필드로 genre를 책 데이터에 추가하였습니다. 사용자는 "fantasy" 장르의 모든 책을 찾고 싶어합니다.
- 쿼리 작성 목표: "fantasy" 장르에 해당하는 모든 책의 제목과 저자를 찾는 MongoDB 쿼리를 함수로 만들어 문제를 해결해 봅니다.
- "fantasy" 장르의 책을 찾는 쿼리입니다.
def find_books_by_genre(db, genre):
query = {"genre": genre}
projection = {"_id": 0, "title": 1, "author": 1}
books = db.books.find(query, projection)
for book in books:
print(book)
find_books_by_genre(db, 'fantasy')
- 문제 2: 감독별 평균 영화 평점 계산
-
- 문제 설명: 각 영화 감독별로 그들의 영화 평점의 평균을 계산하고 싶습니다. 이를 통해 어떤 감독이 가장 높은 평균 평점을 가지고 있는지 알아볼 수 있습니다.
- 쿼리 작성 목표: 모든 영화 감독의 영화 평점 평균을 계산하고, 평균 평점이 높은 순으로 정렬하는 MongoDB 쿼리를 함수로 만들어 문제를 해결해 봅니다.
- 각 감독의 영화 평점 평균을 계산하고, 이를 평균 평점이 높은 순으로 출력하는 쿼리입니다.
def calculate_average_ratings(db):
movies_collection = db.movies
pipeline = [
{"$group": {"_id": "$director", "average_rating": {"$avg": "$rating"}}},
{"$sort": {"average_rating": -1}},
{"$project": {"_id": 0, "director": "$_id", "average_rating": 1}}
]
results = movies_collection.aggregate(pipeline)
for result in results:
print(f"Director: {result['director']}, Average Rating: {result['average_rating']}")
- 문제 3: 특정 사용자의 최근 행동 조회
-
- 문제 설명: 특정 사용자의 최근 행동 로그를 조회하고자 합니다. 이 때, 최신 순으로 정렬하여 최근 5개의 행동만을 보고 싶습니다.
- 쿼리 작성 목표: 사용자 ID가 1인 사용자의 최근 행동 5개를 시간 순으로 정렬하여 조회하는 MongoDB 쿼리를 함수로 만들어 문제를 해결해 봅니다.
- 특정 사용자의 최근 5개 행동을 시간 순으로 조회하는 쿼리입니다.
def find_recent_actions_by_user(db, user_id, limit=5):
user_actions_collection = db.user_actions
query = {"user_id": user_id}
sort_criteria = {"timestamp": -1}
actions = user_actions_collection.find(query).sort(sort_criteria).limit(limit)
for action in actions:
print(action)
- 문제 4: 출판 연도별 책의 수 계산
-
- 문제 설명 : 데이터베이스에 저장된 책 데이터를 이용하여 각 출판 연도별로 출판된 책의 수를 계산하고자 합니다. 이 데이터는 시간에 따른 출판 트렌드를 분석하는 데 사용될 수 있습니다.
- 쿼리 작성 목표 : 각 출판 연도별로 출판된 책의 수를 계산하고, 출판된 책의 수가 많은 순서대로 정렬하는 MongoDB 쿼리를 함수로 만들어 문제를 해결해 봅니다.
- 각 출판 연도별로 출판된 책의 수를 계산하는 쿼리입니다.
def count_books_by_year(db):
books_collection = db.books
pipeline = [
{"$group": {"_id": "$year", "count": {"$sum": 1}}},
{"$sort": {"count": -1}},
{"$project": {"_id": 0, "year": "$_id", "count": 1}}
]
results = books_collection.aggregate(pipeline)
for result in results:
print(f"Year: {result['year']}, Book Count: {result['count']}")
- 문제 5: 특정 사용자의 행동 유형 업데이트
-
- 문제 설명: 특정 사용자의 행동 로그 중, 특정 날짜 이전의 "view" 행동을 "seen"으로 변경하고 싶습니다. 예를 들어, 사용자 ID가 1인 사용자의 2023년 4월 13일 이전의 모든 "view" 행동을 "seen"으로 변경하는 작업입니다.
- 쿼리 작성 목표: 사용자 ID가 1인 사용자의 2023년 4월 13일 이전의 "view" 행동을 "seen"으로 변경하는 MongoDB 업데이트 쿼리를 함수로 만들어 문제를 해결해 봅니다.
- 특정 날짜 이전의 "view" 행동을 "seen"으로 변경하는 쿼리입니다.
from datetime import datetime
def update_user_actions_before_date(db, user_id, date, old_action, new_action):
user_actions_collection = db.user_actions
query = {"user_id": user_id, "action": old_action, "timestamp": {"$lt": date}}
update = {"$set": {"action": new_action}}
result = user_actions_collection.update_many(query, update)
print(f"Updated {result.modified_count} documents.")
🧪 실전 사례
실제 데이터베이스에서 다양한 상황에 맞는 쿼리를 작성하는 과정에서, 각 쿼리의 결과를 통해 데이터 분석 및 관리 업무를 효율적으로 처리할 수 있습니다. 예를 들어, 영화 감독의 평균 평점을 계산하거나, 특정 장르의 책을 조회하는 등 다양한 분석이 가능합니다.
🧠 고급 팁 or 자주 하는 실수
- 집계(aggregation) 파이프라인에서는 group, sort, project 단계를 순차적으로 실행하여 필요한 데이터를 가공하고, 원하는 형태로 출력할 수 있습니다.
- 대량의 데이터 처리 시 update_many, insert_many를 사용하여 여러 문서를 한 번에 처리할 수 있습니다. 이때 성능이 중요한 경우, 인덱스를 잘 활용하는 것이 중요합니다.
- 쿼리 성능 최적화를 위해 인덱스를 설정하고, 자주 사용하는 쿼리의 성능을 점검해야 합니다.
✅ 마무리 요약 및 복습 포인트
- MongoDB에서 데이터를 삽입, 조회, 업데이트하는 방법을 익혔습니다.
- 다양한 문제에 대해 쿼리를 작성하여 실전 예제를 경험했습니다.
- 집계 기능을 활용하여 복잡한 데이터 분석도 가능합니다.
- 효율적인 데이터 관리를 위해 인덱스를 고려하고 성능을 최적화하는 것이 중요합니다.
'과제' 카테고리의 다른 글
Flask와 Jinja 템플릿으로 사용자 목록 웹 페이지 만들어보기(Flask 1일차) (0) | 2025.04.17 |
---|---|
Mini Project : Mini Project. 회원가입폼만들기 (Javascript :2일차 과제)+@ (0) | 2025.04.01 |
페어 과제 (0) | 2025.03.24 |
Database- 데이터베이스 (문제풀이 3일차_심화) (0) | 2025.03.21 |
Database- 데이터베이스 (문제풀이 3일차) (0) | 2025.03.20 |