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-операції на практиці.

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ