JavaRush /Курсы /Модуль 4: FastAPI /Основные операции в MongoDB: создание, чтение, обновление...

Основные операции в MongoDB: создание, чтение, обновление, удаление (CRUD)

Модуль 4: FastAPI
8 уровень , 3 лекция
Открыта

Продолжаем наше увлекательное путешествие в мир MongoDB и баз данных NoSQL.

На прошлых лекциях мы познакомились с основами MongoDB: разобрали её архитектуру, возможности и научились подключать её к нашим проектам.

Сегодня настало время погрузиться в самую суть работы с MongoDB — основные операции с данными.

Говоря проще, научимся создавать, читать, обновлять и удалять данные (CRUD-операции).

CRUD — это основа основ при работе с любой базой данных. MongoDB предлагает весьма гибкий и лаконичный интерфейс для работы с данными.

CRUD расшифровывается как:

  • Create (создание) — добавление новых данных (документов) в коллекцию.
  • Read (чтение) — извлечение данных из коллекции.
  • Update (обновление) — изменение существующих данных.
  • Delete (удаление) — удаление данных.

Давайте по порядку разберём каждую операцию.


1. Создание (Create)

Добавить данные в MongoDB можно с помощью методов insert_one и insert_many.

Пример: добавление одного документа.

Метод insert_one позволяет добавить один документ в коллекцию.


from motor.motor_asyncio import AsyncIOMotorClient
from fastapi import FastAPI

app = FastAPI()

# Подключение к MongoDB
client = AsyncIOMotorClient("mongodb://localhost:27017")
db = client.my_database
collection = db.my_collection

@app.post("/create")
async def create_document():
    document = {"name": "Alice", "age": 25, "city": "Wonderland"}
    result = await collection.insert_one(document)
    return {"inserted_id": str(result.inserted_id)}

👉 Обратите внимание: MongoDB автоматически добавляет поле _id, если вы его не указали. Это уникальный идентификатор документа.

Давайте в следующем примере добавим сразу несколько документов.

Для этого пригодится метод insert_many.


@app.post("/create_many")
async def create_many_documents():
    documents = [
        {"name": "Bob", "age": 30, "city": "Atlantis"},
        {"name": "Charlie", "age": 28, "city": "Springfield"}
    ]
    results = await collection.insert_many(documents)
    return {"inserted_ids": [str(id) for id in results.inserted_ids]}

2. Чтение (Read)

Самая популярная операция — достать данные из базы. MongoDB предоставляет несколько методов для чтения данных, включая find_one и find.

Метод find_one позволяет извлечь первый подходящий документ.


@app.get("/read_one")
async def read_one_document():
    result = await collection.find_one({"name": "Alice"})
    return result

👉 Полезный факт: Возвращаемый документ — это просто словарь Python. Удобно, правда?

Ну а метод find возвращает все документы, соответствующие указанным критериям.


@app.get("/read_many")
async def read_many_documents():
    cursor = collection.find({"age": {"$gt": 20}})  # Документы, где age > 20
    results = []
    async for document in cursor:
        results.append(document)
    return results

MongoDB поддерживает множество операторов для фильтрации данных:

  • $gt и $gte: больше и больше или равно.
  • $lt и $lte: меньше и меньше или равно.
  • $eq и $ne: равно и не равно.
  • $in и $nin: входит или не входит в массив.

Пример фильтрации с несколькими условиями:


criteria = {"age": {"$gt": 20}, "city": "Springfield"}

3. Обновление (Update)

Для изменения существующих данных используются методы update_one, update_many и replace_one.

Метод update_one обновляет первый найденный документ.


@app.put("/update_one")
async def update_one_document():
    filter = {"name": "Alice"}
    update = {"$set": {"age": 26}}
    result = await collection.update_one(filter, update)
    return {"matched_count": result.matched_count, "modified_count": result.modified_count}

👉 Важно: мы используем оператор $set, чтобы указать, какие поля нужно обновить.

Метод update_many обновляет все документы, соответствующие фильтру.


@app.put("/update_many")
async def update_many_documents():
    filter = {"city": "Wonderland"}
    update = {"$set": {"city": "Neverland"}}
    result = await collection.update_many(filter, update)
    return {"matched_count": result.matched_count, "modified_count": result.modified_count}

Если вы хотите заменить документ полностью, то используйте метод replace_one.


@app.put("/replace_one")
async def replace_one_document():
    filter = {"name": "Charlie"}
    new_document = {"name": "Charlie", "age": 35, "country": "USA"}
    result = await collection.replace_one(filter, new_document)
    return {"matched_count": result.matched_count, "modified_count": result.modified_count}

4. Удаление (Delete)

Методы delete_one и delete_many выполняют удаление данных.

Метод delete_one удаляет первый подходящий документ.


@app.delete("/delete_one")
async def delete_one_document():
    filter = {"name": "Alice"}
    result = await collection.delete_one(filter)
    return {"deleted_count": result.deleted_count}

Метод delete_many удаляет все документы, соответствующие фильтру.


@app.delete("/delete_many")
async def delete_many_documents():
    filter = {"city": "Neverland"}
    result = await collection.delete_many(filter)
    return {"deleted_count": result.deleted_count}

Ошибки и особенности при работе с CRUD

  1. Отсутствие схемы: MongoDB не требует указания схемы для данных, что может привести к неструктурированным данным. Следите за консистентностью данных вручную или используйте валидацию на уровне приложения.
  2. Идентификатор _id: значение _id должно быть уникальным. Если вы пытаетесь добавить документ с уже существующим _id, получите ошибку.
  3. Пустой фильтр: если вы передадите пустой фильтр в delete_many или update_many, все документы в коллекции будут затронуты. Это популярная ошибка новичков.

Практика: создаем приложение для управления пользователями

Давайте быстро соберем API, позволяющее управлять коллекцией пользователей.

У нас будут маршруты для создания, чтения, обновления и удаления пользователей.


@app.post("/users")
async def create_user(user: dict):
    result = await collection.insert_one(user)
    return {"inserted_id": str(result.inserted_id)}

@app.get("/users")
async def read_users():
    cursor = collection.find({})
    users = await cursor.to_list(length=100)
    return users

@app.put("/users/{user_id}")
async def update_user(user_id: str, user: dict):
    filter = {"_id": user_id}
    update = {"$set": user}
    result = await collection.update_one(filter, update)
    return {"modified_count": result.modified_count}

@app.delete("/users/{user_id}")
async def delete_user(user_id: str):
    filter = {"_id": user_id}
    result = await collection.delete_one(filter)
    return {"deleted_count": result.deleted_count}

Эти маршруты помогут вам лучше понять CRUD-операции на практике.

1
Задача
Модуль 4: FastAPI, 8 уровень, 3 лекция
Недоступна
Добавление одного документа
Добавление одного документа
1
Задача
Модуль 4: FastAPI, 8 уровень, 3 лекция
Недоступна
Чтение и фильтрация данных
Чтение и фильтрация данных
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ