W3docs

Начало работы с MongoDB

Установите MongoDB, подключитесь через PyMongo и выполните базовые CRUD-операции в Python на понятных рабочих примерах.

В этой главе рассматривается MongoDB и показывается, как использовать её из Python с помощью драйвера PyMongo. К концу главы у вас будет установлена MongoDB, настроено рабочее подключение, и вы получите чёткое представление о том, как вставлять, запрашивать, обновлять и удалять документы.

Что такое MongoDB?

MongoDB — это документная база данных — разновидность NoSQL-базы данных, которая хранит записи в виде JSON-подобных документов вместо строк и столбцов. Каждый документ является самостоятельным объектом, который может содержать вложенные поля и массивы, что делает его естественным выбором для данных, которые не вписываются в фиксированную схему.

Ключевые характеристики:

  • Гибкая схема. Два документа в одной коллекции могут иметь совершенно разные поля.
  • Богатый язык запросов. Фильтрация, проекция, сортировка, ограничение и агрегация выполняются одним вызовом драйвера.
  • Горизонтальная масштабируемость. Встроенное шардирование и наборы реплик обеспечивают работу с большими объёмами данных и высокую доступность.
  • Нативный JSON. Документы хранятся в формате BSON (Binary JSON), поэтому словари Python напрямую отображаются в документы MongoDB.

Когда выбрать MongoDB вместо реляционной базы данных

СитуацияПодходит?
Быстро меняющаяся структура данных (прототипы, API)Да
Иерархические / вложенные данныеДа
Сложные запросы с JOIN по нескольким таблицамПредпочтительнее SQL
Строгие ACID-транзакции по многим таблицамПредпочтительнее SQL
Полнотекстовый поиск в больших масштабахСочетайте с Elasticsearch

Установка MongoDB

Вариант 1 — Локальная установка

Скачайте MongoDB Community Server с сайта mongodb.com/try/download/community, выберите свою операционную систему и следуйте инструкциям установщика. Затем запустите сервер:

# macOS / Linux
mongod --dbpath /data/db

# Windows (PowerShell, run as Administrator)
mongod --dbpath "C:\data\db"

Убедитесь, что MongoDB запущена, открыв второй терминал и выполнив:

mongosh --eval "db.adminCommand('ping')"

Ожидаемый вывод:

{ ok: 1 }

Вариант 2 — Docker (быстрейший способ для разработки)

Если у вас установлен Docker, можно полностью обойтись без локальной установки:

docker run -d --name mongo -p 27017:27017 mongo:7

Это загружает официальный образ MongoDB 7 и открывает порт 27017 на вашем компьютере. Остановить контейнер можно командой docker stop mongo.

Вариант 3 — MongoDB Atlas (облако)

Atlas — полностью управляемый облачный сервис MongoDB с бесплатным тарифом. После регистрации скопируйте строку подключения из панели управления — она выглядит примерно так:

mongodb+srv://username:[email protected]/

Этот URI можно использовать везде, где в данной главе встречается mongodb://localhost:27017/.

Установка драйвера PyMongo

PyMongo — официальный драйвер Python для MongoDB. Установите его с помощью pip:

pip install pymongo

Для работы с MongoDB Atlas дополнительно установите пакет с DNS-резолвером:

pip install "pymongo[srv]"

Проверьте установку:

import pymongo
print(pymongo.version)
# e.g. 4.7.3

Подключение к MongoDB

MongoClient — точка входа для всех операций драйвера. Создайте один клиент на приложение и переиспользуйте его — клиент управляет внутренним пулом соединений.

from pymongo import MongoClient

# Local server with default host and port
client = MongoClient("mongodb://localhost:27017/")

# Verify connectivity (raises ConnectionFailure if the server is unreachable)
client.admin.command("ping")
print("Connected successfully")

В продакшен-коде всегда явно обрабатывайте ошибки подключения:

from pymongo import MongoClient
from pymongo.errors import ConnectionFailure

client = MongoClient("mongodb://localhost:27017/", serverSelectionTimeoutMS=3000)

try:
    client.admin.command("ping")
    print("Connected to MongoDB")
except ConnectionFailure as e:
    print("Connection failed:", e)

Формат строки подключения

mongodb://[username:password@]host[:port][/database][?options]

Распространённые параметры:

ПараметрПримерНазначение
authSourceauthSource=adminБаза данных для аутентификации
replicaSetreplicaSet=rs0Подключение к набору реплик
tls=truetls=trueВключить TLS/SSL
serverSelectionTimeoutMSserverSelectionTimeoutMS=5000Таймаут выбора сервера

Базы данных и коллекции

MongoDB организует данные в двухуровневую иерархию:

  • База данных группирует связанные коллекции (аналог схемы или базы данных в SQL).
  • Коллекция содержит документы (аналог таблицы SQL, но без фиксированной схемы).

Обе создаются лениво — они начинают существовать в момент первой вставки документа. Команды CREATE DATABASE и CREATE TABLE не нужны.

from pymongo import MongoClient

client = MongoClient("mongodb://localhost:27017/")

# Reference a database (not yet created on disk)
db = client["mystore"]

# Reference a collection inside it (also not yet on disk)
products = db["products"]

# The database and collection are created when the first document is inserted

Базовые CRUD-операции

Приведённые ниже примеры строятся один на другом. Если вы следуете руководству в интерактивном режиме, выполняйте их по порядку.

Create — вставка документов

Используйте insert_one() для одного документа и insert_many() для группы:

from pymongo import MongoClient

client = MongoClient("mongodb://localhost:27017/")
db = client["mystore"]
products = db["products"]

# Insert a single document
result = products.insert_one({
    "name": "Laptop",
    "brand": "Acme",
    "price": 999.99,
    "in_stock": True
})
print("Inserted id:", result.inserted_id)

# Insert multiple documents at once
new_products = [
    {"name": "Mouse",    "brand": "Acme", "price": 29.99,  "in_stock": True},
    {"name": "Keyboard", "brand": "Acme", "price": 79.99,  "in_stock": False},
    {"name": "Monitor",  "brand": "Zeta", "price": 349.99, "in_stock": True},
]
batch_result = products.insert_many(new_products)
print("Inserted ids:", batch_result.inserted_ids)

MongoDB автоматически добавляет поле _id (типа ObjectId) к каждому документу, если вы не указали его явно. Это поле является первичным ключом и всегда уникально в пределах коллекции.

Read — запрос документов

find_one() возвращает первый подходящий документ (или None). find() возвращает курсор, по которому можно итерироваться.

# Retrieve one document (no filter = the first document in natural order)
doc = products.find_one()
print(doc)

# Retrieve all documents in the collection
for p in products.find():
    print(p["name"], "-", p["price"])

# Filter: products that are in stock
for p in products.find({"in_stock": True}):
    print(p["name"])

# Projection: return only name and price (exclude _id)
for p in products.find({}, {"_id": 0, "name": 1, "price": 1}):
    print(p)

Операторы запросов

Язык запросов MongoDB использует операторы с префиксом $:

# Products cheaper than £100
cheap = products.find({"price": {"$lt": 100}})

# In-stock products from brand "Acme" or "Zeta"
multi = products.find({
    "in_stock": True,
    "brand": {"$in": ["Acme", "Zeta"]}
})

# Price between 50 and 500 (inclusive)
range_q = products.find({"price": {"$gte": 50, "$lte": 500}})

Распространённые операторы сравнения:

ОператорЗначение
$eqРавно (по умолчанию при использовании {"field": value})
$neНе равно
$gt / $gteБольше / больше или равно
$lt / $lteМеньше / меньше или равно
$inЗначение входит в список
$ninЗначение не входит в список

Update — изменение документов

update_one() изменяет первый подходящий документ. update_many() изменяет все совпадения. Всегда используйте оператор $set для изменения конкретных полей — без него вы замените весь документ целиком.

# Update a single document: change the price of "Mouse"
update_result = products.update_one(
    {"name": "Mouse"},          # filter
    {"$set": {"price": 24.99}}  # update
)
print("Matched:", update_result.matched_count,
      "Modified:", update_result.modified_count)

# Mark all Acme products as in stock
products.update_many(
    {"brand": "Acme"},
    {"$set": {"in_stock": True}}
)

# Increment a field value
products.update_one(
    {"name": "Laptop"},
    {"$inc": {"price": -50}}  # reduce price by 50
)

Распространённые операторы обновления:

ОператорДействие
$setУстановить одно или несколько полей
$unsetУдалить поле
$incУвеличить числовое поле
$pushДобавить значение в array-поле
$pullУдалить значение из array-поля

Delete — удаление документов

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

# Remove a single document
del_result = products.delete_one({"name": "Keyboard"})
print("Deleted count:", del_result.deleted_count)

# Remove all out-of-stock items
products.delete_many({"in_stock": False})

# Confirm what is left
print("Remaining products:")
for p in products.find({}, {"_id": 0, "name": 1}):
    print(" -", p["name"])

Типичные ловушки

Ленивое создание может скрывать опечатки

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

# Intended: client["mystore"]   Actual: client["mystoree"]
db = client["mystoree"]  # no error, but your data goes to the wrong database

Решение: определяйте имена баз данных и коллекций как константы на уровне модуля:

DB_NAME  = "mystore"
COL_NAME = "products"

db = client[DB_NAME]
products = db[COL_NAME]

Ошибки соединения проявляются только при первой операции

MongoClient() завершается успешно, даже если MongoDB не запущена. Ошибка возникает только при выполнении реального запроса. Используйте serverSelectionTimeoutMS и проверку ping при запуске (как показано в разделе о подключении выше), чтобы быстро обнаруживать проблему.

Отсутствие $set заменяет весь документ

# WRONG — replaces the whole document with just {"price": 24.99}
products.update_one({"name": "Mouse"}, {"price": 24.99})

# CORRECT — only changes the price field
products.update_one({"name": "Mouse"}, {"$set": {"price": 24.99}})

find() возвращает курсор, а не список

Курсор работает лениво — документы загружаются с сервера только по мере итерации. Если вам нужен обычный список, явно преобразуйте его:

all_products = list(products.find())

Будьте осторожны с большими коллекциями: загрузка всего сразу в память может исчерпать RAM.

Что дальше

В этой главе рассмотрены основы. Остальные главы серии Python MongoDB подробнее раскрывают каждую тему:

  • MongoDB Create Database — как работает ленивое создание и как проверить существование базы данных.
  • MongoDB Create Collection — параметры создания коллекций и схемы валидации.
  • MongoDB Insertinsert_one(), insert_many() и обработка ошибок дублирующихся ключей.
  • MongoDB Find — проекции, курсоры и сортировка.
  • MongoDB Query — полный справочник операторов запросов.
  • MongoDB Updateupdate_one(), update_many(), upsert и операторы массивов.
  • MongoDB Delete — безопасные шаблоны удаления и drop().
  • MongoDB Sort — сортировка по одному и нескольким полям.
  • MongoDB Limit — пагинация с помощью limit() и skip().
  • MongoDB Drop Collection — полное удаление коллекции.
Was this page helpful?