📌Mongo DB 심화 5문제 with python

2025. 3. 27. 17:05·과제

📌 개념 정리

이 포스팅에서는 MongoDB를 활용한 데이터 삽입, 조회, 업데이트 및 집계(aggregation)에 대한 여러 문제를 다룹니다. 예제 코드와 함께 MongoDB의 기본적인 사용법을 익히고, 실용적인 쿼리를 통해 데이터베이스 관리 기술을 향상시킬 수 있습니다.


🚦 동작 원리 및 구조

  1. MongoDB 연결
    • MongoClient를 사용하여 로컬 MongoDB 서버에 연결합니다.
    • 데이터베이스와 컬렉션을 선택하여 작업을 진행합니다.
  2. 데이터 삽입
    • insert_many를 사용하여 여러 문서를 한 번에 삽입할 수 있습니다.
  3. 데이터 조회
    • find와 aggregate 메서드를 사용하여 조건에 맞는 데이터를 조회하고, 집계할 수 있습니다.
  4. 데이터 업데이트
    • update_many 메서드를 사용하여 조건에 맞는 데이터를 일괄 수정할 수 있습니다.

💻 코드 예시 및 흐름 분석

  1. 데이터 삽입
    • 먼저 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()
  1. 장르 추가
    • 기존의 책 데이터에 "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. 문제 해결 예시
    • 문제 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를 사용하여 여러 문서를 한 번에 처리할 수 있습니다. 이때 성능이 중요한 경우, 인덱스를 잘 활용하는 것이 중요합니다.
  • 쿼리 성능 최적화를 위해 인덱스를 설정하고, 자주 사용하는 쿼리의 성능을 점검해야 합니다.

✅ 마무리 요약 및 복습 포인트

  1. MongoDB에서 데이터를 삽입, 조회, 업데이트하는 방법을 익혔습니다.
  2. 다양한 문제에 대해 쿼리를 작성하여 실전 예제를 경험했습니다.
  3. 집계 기능을 활용하여 복잡한 데이터 분석도 가능합니다.
  4. 효율적인 데이터 관리를 위해 인덱스를 고려하고 성능을 최적화하는 것이 중요합니다.

'과제' 카테고리의 다른 글

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
'과제' 카테고리의 다른 글
  • Flask와 Jinja 템플릿으로 사용자 목록 웹 페이지 만들어보기(Flask 1일차)
  • Mini Project : Mini Project. 회원가입폼만들기 (Javascript :2일차 과제)+@
  • 페어 과제
  • Database- 데이터베이스 (문제풀이 3일차_심화)
Chansman
Chansman
안녕하세요! 코딩을 시작한 지 얼마 되지 않은 초보 개발자 찬스맨입니다. 이 블로그는 제 학습 기록을 남기고, 다양한 코딩 실습을 통해 성장하는 과정을 공유하려고 합니다. 초보자의 눈높이에 맞춘 실습과 팁, 그리고 개발하면서 겪은 어려움과 해결 과정을 솔직하게 풀어내려 합니다. 함께 성장하는 개발자 커뮤니티가 되기를 바랍니다.
  • Chansman
    찬스맨의 프로그래밍 스토리
    Chansman
  • 전체
    오늘
    어제
    • 분류 전체보기 (798)
      • Python (32)
      • 프로젝트 (113)
      • 과제 (25)
      • Database (40)
      • 멘토링 (11)
      • 특강 (37)
      • 기술블로그 (41)
      • 기술블로그-Fastapi편 (33)
      • 기술블로그-Django편 (154)
      • 기술블로그-Flask편 (36)
      • AI 분석 (5)
      • HTML & CSS (31)
      • JavaScript (17)
      • AWS_Cloud (21)
      • 웹스크래핑과 데이터 수집 (14)
      • Flask (42)
      • Django (77)
      • Fastapi (16)
      • 연예 (14)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    classaction
    college reunions
    btsreunion
    bts
    titaniumcase
    homebartrend
    americaparty
    livebroadcast
    hotcoffeecase
    smartphonedurability
    youngprofessionals
    gpterror
    btsjungkook
    global politics
    self-growth
    뷔
    basalcellcarcinoma
    chatgpterror
    lawsuitculture
    remittance
    chinanightlife
    life reflection
    newpoliticalparty
    travel ban
    americanlaw
    trumpmuskclash
    btscomeback
    RM
    btsdischarge
    urbantrends
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Chansman
📌Mongo DB 심화 5문제 with python
상단으로

티스토리툴바