MongoDB
Введение
MongoDB — это документоориентированная NoSQL база данных. Вместо таблиц и строк данные хранятся в документах в формате, похожем на JSON, что обеспечивает большую гибкость модели данных.
Netuno предоставляет ресурс _mongo для интеграции с MongoDB с low-code-абстракцией над официальным клиентом MongoDB для Java, доступный для различных языков программирования, поддерживаемых Netuno: JavaScript, Python, Ruby, Kotlin и Groovy.
Перед началом рекомендуется ознакомиться с тем, как создавать сервисы в Netuno, см. руководство REST — веб-сервисы.
Пример реализации операций, представленных здесь, доступен в примере сервиса mongo.js, который находится по пути:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
apps/демо/server/services/примеры/javascript/mongo.js
apps/демо/server/services/примеры/javascript/mongo.ts
apps/демо/server/services/примеры/javascript/mongo.py
apps/демо/server/services/примеры/javascript/mongo.rb
apps/демо/server/services/примеры/javascript/mongo.kts
apps/демо/server/services/примеры/javascript/mongo.groovy
Установка MongoDB
С помощью Docker
Если Docker установлен, достаточно загрузить образ MongoDB и запустить новый контейнер:
docker pull mongo
docker run -d --name mongo -p 27017:27017 mongo
Таким образом, MongoDB будет доступен по адресу localhost:27017 без аутентификации.
Чтобы создать пользователя базы данных в соответствии с конфигурацией приложения, выполните:
docker exec -it mongo mongosh товары_бд --eval 'db.createUser({ user: "товары_пользователь", pwd: "12345678", roles: [{ role: "readWrite", db: "товары_бд" }] })'
В Ubuntu
MongoDB не включён в официальные репозитории Ubuntu, поэтому перед установкой необходимо добавить официальный репозиторий:
sudo apt-get install gnupg curl
curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | sudo gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg --dearmor
echo "deb [ signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] http://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list
sudo apt-get update
sudo apt-get install -y mongodb-org
После установки можно запустить службу с помощью:
sudo systemctl start mongod
В Windows
Запустите скачанный установщик и на шаге Service Configuration включите Install MongoD as a Service, чтобы MongoDB запускался автоматически. MongoDB будет доступен по адресу localhost:27017 без аутентификации.
Обратитесь к официальной документации MongoDB для других дистрибутивов и версий.
Настройка приложения
Настройка подключений MongoDB выполняется в файле конфигурации приложения в соответствии с окружением:
config/_development.json
Подробнее о файлах конфигурации приложения.
В файле конфигурации добавьте блок mongo, где каждый ключ идентифицирует подключение:
{
...
"mongo": {
"магазин": "mongodb://магазин_пользователь:12345678@localhost/магазин_бд",
"товары": {
"username": "товары_пользователь",
"password": "12345678",
"host": "127.0.0.1",
"port": "27017",
"database": "товары_бд"
}
},
...
}
Подключение можно определить двумя способами:
- Как URL подключения — значение представляет собой просто строку, например
"mongodb://магазин_пользователь:12345678@localhost/магазин_бд". - Как объект конфигурации — с полями:
url— если задан, используется напрямую как URL подключения, остальные поля игнорируются.protocol— протокол подключения, по умолчаниюmongodb.usernameиpassword— учётные данные для доступа.host— адрес сервера, по умолчаниюlocalhost.port— порт подключения, по умолчанию27017.database— имя базы данных, по умолчанию имя ключа подключения.params— дополнительные параметры подключения, добавляемые к URL, например{ "authSource": "admin" }. Применяются только когда URL строится из полей объекта.
Подключение не обязано быть основной базой данных приложения. В отличие от конфигурации
db, блокmongoнезависим и позволяет использовать несколько подключений одновременно.
Инициализация подключения
Первый шаг — инициализировать клиент MongoDB с помощью ресурса _mongo.init(...), передав имя ключа конфигурации или непосредственно URL подключения:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const клиент = _mongo.init("товары")
const клиент = _mongo.init("товары")
клиент = _mongo.init("товары")
клиент = _mongo.init("товары")
val клиент = _mongo.init("товары")
def клиент = _mongo.init("товары")
Также можно инициализировать подключение напрямую с помощью URL:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const клиент = _mongo.init("mongodb://localhost:27017/товары_бд")
const клиент = _mongo.init("mongodb://localhost:27017/товары_бд")
клиент = _mongo.init("mongodb://localhost:27017/товары_бд")
клиент = _mongo.init("mongodb://localhost:27017/товары_бд")
val клиент = _mongo.init("mongodb://localhost:27017/товары_бд")
def клиент = _mongo.init("mongodb://localhost:27017/товары_бд")
При вызове
_mongo.init()без аргументов используется ключ конфигурацииdefault. Рекомендуется всегда передавать имя ключа или URL, чтобы явно указать используемое подключение.
База данных и коллекции
После инициализации клиента получите экземпляр базы данных с помощью database("имя"). Затем можно создавать коллекции и обращаться к существующей коллекции:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const бд = клиент.database("товары_бд")
бд.createCollection("товар")
const коллекция = бд.collection("товар")
const бд = клиент.database("товары_бд")
бд.createCollection("товар")
const коллекция = бд.collection("товар")
бд = клиент.database("товары_бд")
бд.createCollection("товар")
коллекция = бд.collection("товар")
бд = клиент.database("товары_бд")
бд.createCollection("товар")
коллекция = бд.collection("товар")
val бд = клиент.database("товары_бд")
бд.createCollection("товар")
val коллекция = бд.collection("товар")
def бд = клиент.database("товары_бд")
бд.createCollection("товар")
def коллекция = бд.collection("товар")
Можно проверить подключение к базе данных с помощью ping() и вывести список всех существующих коллекций с помощью collectionNames():
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
бд.ping()
const имена = бд.collectionNames()
бд.ping()
const имена = бд.collectionNames()
бд.ping()
имена = бд.collectionNames()
бд.ping()
имена = бд.collectionNames()
бд.ping()
val имена = бд.collectionNames()
бд.ping()
def имена = бд.collectionNames()
Можно переименовать коллекцию с помощью renameCollection(), передав полное имя с базой данных или имя базы данных и новое имя коллекции отдельно:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
коллекция.renameCollection("товары_бд.архив_товаров")
коллекция.renameCollection("архив_бд", "архив_товаров")
коллекция.renameCollection("товары_бд.архив_товаров")
коллекция.renameCollection("архив_бд", "архив_товаров")
коллекция.renameCollection("товары_бд.архив_товаров")
коллекция.renameCollection("архив_бд", "архив_товаров")
коллекция.renameCollection("товары_бд.архив_товаров")
коллекция.renameCollection("архив_бд", "архив_товаров")
коллекция.renameCollection("товары_бд.архив_товаров")
коллекция.renameCollection("архив_бд", "архив_товаров")
коллекция.renameCollection("товары_бд.архив_товаров")
коллекция.renameCollection("архив_бд", "архив_товаров")
Чтобы удалить коллекцию и все её документы, используйте drop():
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
коллекция.drop()
коллекция.drop()
коллекция.drop()
коллекция.drop()
коллекция.drop()
коллекция.drop()
Вставка документов
Данные представляются с помощью ресурса _val: _val.map() для документов и _val.list() для списков значений.
Вставка одного документа
С помощью insertOne() вставляет документ и получает сгенерированный ID:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const идентификатор = коллекция.insertOne(
_val.map()
.set("название", "Ноутбук")
.set("количество", 22)
.set("цена", 100)
.set("категория", "компьютеры")
)
const идентификатор = коллекция.insertOne(
_val.map()
.set("название", "Ноутбук")
.set("количество", 22)
.set("цена", 100)
.set("категория", "компьютеры")
)
идентификатор = коллекция.insertOne(
_val.map()
.set("название", "Ноутбук")
.set("количество", 22)
.set("цена", 100)
.set("категория", "компьютеры")
)
идентификатор = коллекция.insertOne(
_val.map()
.set("название", "Ноутбук")
.set("количество", 22)
.set("цена", 100)
.set("категория", "компьютеры")
)
val идентификатор = коллекция.insertOne(
_val.map()
.set("название", "Ноутбук")
.set("количество", 22)
.set("цена", 100)
.set("категория", "компьютеры")
)
def идентификатор = коллекция.insertOne(
_val.map()
.set("название", "Ноутбук")
.set("количество", 22)
.set("цена", 100)
.set("категория", "компьютеры")
)
Документы могут содержать вложенные структуры, такие как списки и другие документы:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
коллекция.insertOne(
_val.map()
.set("название", "Планшет")
.set("теги",
_val.list()
.add("акция")
.add("новинка")
)
.set("детали",
_val.map()
.set("цвет", "синий")
.set("запас", 10)
)
)
коллекция.insertOne(
_val.map()
.set("название", "Планшет")
.set("теги",
_val.list()
.add("акция")
.add("новинка")
)
.set("детали",
_val.map()
.set("цвет", "синий")
.set("запас", 10)
)
)
коллекция.insertOne(
_val.map()
.set("название", "Планшет")
.set("теги",
_val.list()
.add("акция")
.add("новинка")
)
.set("детали",
_val.map()
.set("цвет", "синий")
.set("запас", 10)
)
)
коллекция.insertOne(
_val.map()
.set("название", "Планшет")
.set("теги",
_val.list()
.add("акция")
.add("новинка")
)
.set("детали",
_val.map()
.set("цвет", "синий")
.set("запас", 10)
)
)
коллекция.insertOne(
_val.map()
.set("название", "Планшет")
.set("теги",
_val.list()
.add("акция")
.add("новинка")
)
.set("детали",
_val.map()
.set("цвет", "синий")
.set("запас", 10)
)
)
коллекция.insertOne(
_val.map()
.set("название", "Планшет")
.set("теги",
_val.list()
.add("акция")
.add("новинка")
)
.set("детали",
_val.map()
.set("цвет", "синий")
.set("запас", 10)
)
)
Вставка нескольких документов
С помощью insertMany() вставляет несколько документов за один раз, получая список сгенерированных ID:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const идентификаторы = коллекция.insertMany(
_val.list()
.add(
_val.map()
.set("название", "Смартфон")
.set("количество", 18)
)
.add(
_val.map()
.set("название", "Монитор")
.set("количество", 8)
)
)
const идентификаторы = коллекция.insertMany(
_val.list()
.add(
_val.map()
.set("название", "Смартфон")
.set("количество", 18)
)
.add(
_val.map()
.set("название", "Монитор")
.set("количество", 8)
)
)
идентификаторы = коллекция.insertMany(
_val.list()
.add(
_val.map()
.set("название", "Смартфон")
.set("количество", 18)
)
.add(
_val.map()
.set("название", "Монитор")
.set("количество", 8)
)
)
идентификаторы = коллекция.insertMany(
_val.list()
.add(
_val.map()
.set("название", "Смартфон")
.set("количество", 18)
)
.add(
_val.map()
.set("название", "Монитор")
.set("количество", 8)
)
)
val идентификаторы = коллекция.insertMany(
_val.list()
.add(
_val.map()
.set("название", "Смартфон")
.set("количество", 18)
)
.add(
_val.map()
.set("название", "Монитор")
.set("количество", 8)
)
)
def идентификаторы = коллекция.insertMany(
_val.list()
.add(
_val.map()
.set("название", "Смартфон")
.set("количество", 18)
)
.add(
_val.map()
.set("название", "Монитор")
.set("количество", 8)
)
)
Запрос документов
Метод find() возвращает MongoFindIterable, из которого документы получаются с помощью all() (все) или first() (первый, или null, если документов нет).
Чтобы получить все документы коллекции:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const документы = коллекция.find().all()
const документы = коллекция.find().all()
документы = коллекция.find().all()
документы = коллекция.find().all()
val документы = коллекция.find().all()
def документы = коллекция.find().all()
Чтобы выполнить запрос с фильтром, используйте фабрику _mongo.filters():
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const документы = коллекция.find(
_mongo.filters().eq("название", "Ноутбук")
).all()
const документы = коллекция.find(
_mongo.filters().eq("название", "Ноутбук")
).all()
документы = коллекция.find(
_mongo.filters().eq("название", "Ноутбук")
).all()
документы = коллекция.find(
_mongo.filters().eq("название", "Ноутбук")
).all()
val документы = коллекция.find(
_mongo.filters().eq("название", "Ноутбук")
).all()
def документы = коллекция.find(
_mongo.filters().eq("название", "Ноутбук")
).all()
Фильтры
Фабрика _mongo.filters() предоставляет основные операторы запросов MongoDB:
| Оператор | Описание |
|---|---|
eq("поле", значение) | Равно значению. |
ne("поле", значение) | Не равно значению. |
gt("поле", значение) | Больше значения. |
gte("поле", значение) | Больше или равно значению. |
lt("поле", значение) | Меньше значения. |
lte("поле", значение) | Меньше или равно значению. |
in("поле", значение1, значение2, ...) | Равно любому из значений. |
nin("поле", значение1, значение2, ...) | Не равно ни одному из значений. |
and(фильтр1, фильтр2, ...) | Соответствует всем фильтрам. |
or(фильтр1, фильтр2, ...) | Соответствует хотя бы одному из фильтров. |
not(фильтр) | Не соответствует фильтру. |
regex("поле", "шаблон") | Соответствует регулярному выражению. |
exists("поле") | Поле существует в документе. |
text("поиск") | Текстовый поиск. |
type("поле", "тип") | Поле имеет указанный тип. |
mod("поле", делитель, остаток) | Остаток от деления поля на делитель равен значению. |
where("выражение") | Соответствует документам, удовлетворяющим выражению JavaScript, например "this.цена > 100". |
size("поле", n) | Поле-массив содержит ровно n элементов. |
Например, чтобы получить товары с ценой выше 50 и количеством меньше 30:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const документы = коллекция.find(
_mongo.filters().and(
_mongo.filters().gt("цена", 50),
_mongo.filters().lt("количество", 30)
)
).all()
const документы = коллекция.find(
_mongo.filters().and(
_mongo.filters().gt("цена", 50),
_mongo.filters().lt("количество", 30)
)
).all()
документы = коллекция.find(
_mongo.filters().and(
_mongo.filters().gt("цена", 50),
_mongo.filters().lt("количество", 30)
)
).all()
документы = коллекция.find(
_mongo.filters().and(
_mongo.filters().gt("цена", 50),
_mongo.filters().lt("количество", 30)
)
).all()
val документы = коллекция.find(
_mongo.filters().and(
_mongo.filters().gt("цена", 50),
_mongo.filters().lt("количество", 30)
)
).all()
def документы = коллекция.find(
_mongo.filters().and(
_mongo.filters().gt("цена", 50),
_mongo.filters().lt("количество", 30)
)
).all()
Или чтобы получить товары, название которых соответствует регулярному выражению:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const документы = коллекция.find(
_mongo.filters().regex("название", "^[НС]")
).all()
const документы = коллекция.find(
_mongo.filters().regex("название", "^[НС]")
).all()
документы = коллекция.find(
_mongo.filters().regex("название", "^[НС]")
).all()
документы = коллекция.find(
_mongo.filters().regex("название", "^[НС]")
).all()
val документы = коллекция.find(
_mongo.filters().regex("название", "^[НС]")
).all()
def документы = коллекция.find(
_mongo.filters().regex("название", "^[НС]")
).all()
Перебор результатов
С результатом запроса можно перебрать все найденные документы:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
for (const документ of коллекция.find().all()) {
_out.println(документ.getString("название"))
}
for (const документ of коллекция.find().all()) {
_out.println(документ.getString("название"))
}
for документ in коллекция.find().all():
_out.println(документ.getString("название"))
коллекция.find().all().each do |документ|
_out.println(документ.getString("название"))
end
for (документ in коллекция.find().all()) {
_out.println(документ.getString("название"))
}
for (документ in коллекция.find().all()) {
_out.println(документ.getString("название"))
}
Также можно перебрать результаты с помощью forEach(), передав функцию:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
коллекция.find().forEach((документ) =>
_out.println(документ.getString("название"))
)
коллекция.find().forEach((документ) =>
_out.println(документ.getString("название"))
)
коллекция.find().forEach(
lambda документ: _out.println(документ.getString("название"))
)
коллекция.find().forEach do |документ|
_out.println(документ.getString("название"))
end
коллекция.find().forEach { документ ->
_out.println(документ.getString("название"))
}
коллекция.find().forEach { документ ->
_out.println(документ.getString("название"))
}
Сортировка
С помощью фабрики _mongo.sorts() можно задать порядок результатов по возрастанию или убыванию:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const документы = коллекция.find().sort(
_mongo.sorts().descending("цена")
).all()
const документы = коллекция.find().sort(
_mongo.sorts().descending("цена")
).all()
документы = коллекция.find().sort(
_mongo.sorts().descending("цена")
).all()
документы = коллекция.find().sort(
_mongo.sorts().descending("цена")
).all()
val документы = коллекция.find().sort(
_mongo.sorts().descending("цена")
).all()
def документы = коллекция.find().sort(
_mongo.sorts().descending("цена")
).all()
Чтобы отсортировать по нескольким полям, используйте orderBy():
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const документы = коллекция.find().sort(
_mongo.sorts().orderBy(
_mongo.sorts().descending("цена"),
_mongo.sorts().ascending("количество")
)
).all()
const документы = коллекция.find().sort(
_mongo.sorts().orderBy(
_mongo.sorts().descending("цена"),
_mongo.sorts().ascending("количество")
)
).all()
документы = коллекция.find().sort(
_mongo.sorts().orderBy(
_mongo.sorts().descending("цена"),
_mongo.sorts().ascending("количество")
)
).all()
документы = коллекция.find().sort(
_mongo.sorts().orderBy(
_mongo.sorts().descending("цена"),
_mongo.sorts().ascending("количество")
)
).all()
val документы = коллекция.find().sort(
_mongo.sorts().orderBy(
_mongo.sorts().descending("цена"),
_mongo.sorts().ascending("количество")
)
).all()
def документы = коллекция.find().sort(
_mongo.sorts().orderBy(
_mongo.sorts().descending("цена"),
_mongo.sorts().ascending("количество")
)
).all()
Проекция полей
С помощью фабрики _mongo.projections() можно ограничить поля, возвращаемые в документах:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const документы = коллекция.find().projection(
_mongo.projections().include("название", "количество")
).all()
const документы = коллекция.find().projection(
_mongo.projections().include("название", "количество")
).all()
документы = коллекция.find().projection(
_mongo.projections().include("название", "количество")
).all()
документы = коллекция.find().projection(
_mongo.projections().include("название", "количество")
).all()
val документы = коллекция.find().projection(
_mongo.projections().include("название", "количество")
).all()
def документы = коллекция.find().projection(
_mongo.projections().include("название", "количество")
).all()
Чтобы объединить несколько проекций:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const документы = коллекция.find().projection(
_mongo.projections().fields(
_mongo.projections().include("название", "количество"),
_mongo.projections().excludeId()
)
).all()
const документы = коллекция.find().projection(
_mongo.projections().fields(
_mongo.projections().include("название", "количество"),
_mongo.projections().excludeId()
)
).all()
документы = коллекция.find().projection(
_mongo.projections().fields(
_mongo.projections().include("название", "количество"),
_mongo.projections().excludeId()
)
).all()
документы = коллекция.find().projection(
_mongo.projections().fields(
_mongo.projections().include("название", "количество"),
_mongo.projections().excludeId()
)
).all()
val документы = коллекция.find().projection(
_mongo.projections().fields(
_mongo.projections().include("название", "количество"),
_mongo.projections().excludeId()
)
).all()
def документы = коллекция.find().projection(
_mongo.projections().fields(
_mongo.projections().include("название", "количество"),
_mongo.projections().excludeId()
)
).all()
Доступны следующие типы проекций:
| Проекция | Описание |
|---|---|
include("поле", ...) | Включает только указанные поля. |
exclude("поле", ...) | Исключает указанные поля. |
excludeId() | Исключает поле _id. |
fields(проекция1, ...) | Объединяет проекции. |
slice("поле", n) | Включает только первые n элементов поля-массива. |
slice("поле", смещение, n) | Включает n элементов поля-массива, начиная после первых смещение элементов. |
elemMatch("поле") | Включает только первый элемент поля-массива. |
elemMatch("поле", фильтр) | Включает только первый элемент массива, соответствующий фильтру. |
computed("поле", выражение) | Добавляет вычисляемое поле на основе выражения агрегации. |
Ограничения и пропуски
С помощью limit() и skip() можно управлять количеством возвращаемых результатов:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const документы = коллекция.find()
.skip(1)
.limit(2)
.all()
const документы = коллекция.find()
.skip(1)
.limit(2)
.all()
документы = коллекция.find()
.skip(1)
.limit(2)
.all()
документы = коллекция.find()
.skip(1)
.limit(2)
.all()
val документы = коллекция.find()
.skip(1)
.limit(2)
.all()
def документы = коллекция.find()
.skip(1)
.limit(2)
.all()
Обновление документов
С помощью фабрики _mongo.updates() можно определить изменения для применения, а с помощью updateOne() или updateMany() применить изменения к документам, соответствующим фильтру:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
коллекция.updateOne(
_mongo.filters().eq("название", "Ноутбук"),
_mongo.updates().set("количество", 42)
)
коллекция.updateMany(
_mongo.filters().eq("категория", "компьютеры"),
_mongo.updates().set("категория", "избранное")
)
коллекция.updateOne(
_mongo.filters().eq("название", "Ноутбук"),
_mongo.updates().set("количество", 42)
)
коллекция.updateMany(
_mongo.filters().eq("категория", "компьютеры"),
_mongo.updates().set("категория", "избранное")
)
коллекция.updateOne(
_mongo.filters().eq("название", "Ноутбук"),
_mongo.updates().set("количество", 42)
)
коллекция.updateMany(
_mongo.filters().eq("категория", "компьютеры"),
_mongo.updates().set("категория", "избранное")
)
коллекция.updateOne(
_mongo.filters().eq("название", "Ноутбук"),
_mongo.updates().set("количество", 42)
)
коллекция.updateMany(
_mongo.filters().eq("категория", "компьютеры"),
_mongo.updates().set("категория", "избранное")
)
коллекция.updateOne(
_mongo.filters().eq("название", "Ноутбук"),
_mongo.updates().set("количество", 42)
)
коллекция.updateMany(
_mongo.filters().eq("категория", "компьютеры"),
_mongo.updates().set("категория", "избранное")
)
коллекция.updateOne(
_mongo.filters().eq("название", "Ноутбук"),
_mongo.updates().set("количество", 42)
)
коллекция.updateMany(
_mongo.filters().eq("категория", "компьютеры"),
_mongo.updates().set("категория", "избранное")
)
Фабрика _mongo.updates() предоставляет операторы обновления:
| Оператор | Описание |
|---|---|
set("поле", значение) | Устанавливает значение поля. |
unset("поле") | Удаляет поле из документа. |
rename("поле", "новоеИмя") | Переименовывает поле. |
push("поле", значение) | Добавляет значение в массив. |
combine(обновление1, обновление2, ...) | Объединяет несколько обновлений в одно. |
Чтобы применить несколько изменений за один раз, используйте combine():
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const объединённое = _mongo.updates().combine(
_mongo.updates().set("количество", 42),
_mongo.updates().rename("прочее", "дополнительное")
)
коллекция.updateOne(
_mongo.filters().eq("название", "Ноутбук"),
объединённое
)
const объединённое = _mongo.updates().combine(
_mongo.updates().set("количество", 42),
_mongo.updates().rename("прочее", "дополнительное")
)
коллекция.updateOne(
_mongo.filters().eq("название", "Ноутбук"),
объединённое
)
объединённое = _mongo.updates().combine(
_mongo.updates().set("количество", 42),
_mongo.updates().rename("прочее", "дополнительное")
)
коллекция.updateOne(
_mongo.filters().eq("название", "Ноутбук"),
объединённое
)
объединённое = _mongo.updates().combine(
_mongo.updates().set("количество", 42),
_mongo.updates().rename("прочее", "дополнительное")
)
коллекция.updateOne(
_mongo.filters().eq("название", "Ноутбук"),
объединённое
)
val объединённое = _mongo.updates().combine(
_mongo.updates().set("количество", 42),
_mongo.updates().rename("прочее", "дополнительное")
)
коллекция.updateOne(
_mongo.filters().eq("название", "Ноутбук"),
объединённое
)
def объединённое = _mongo.updates().combine(
_mongo.updates().set("количество", 42),
_mongo.updates().rename("прочее", "дополнительное")
)
коллекция.updateOne(
_mongo.filters().eq("название", "Ноутбук"),
объединённое
)
Найти и обновить
С помощью findOneAndUpdate() находит и атомарно обновляет документ, возвращая исходный документ (или null, если документов нет):
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const старый = коллекция.findOneAndUpdate(
_mongo.filters().eq("название", "Ноутбук"),
_mongo.updates().set("количество", 42)
)
const старый = коллекция.findOneAndUpdate(
_mongo.filters().eq("название", "Ноутбук"),
_mongo.updates().set("количество", 42)
)
старый = коллекция.findOneAndUpdate(
_mongo.filters().eq("название", "Ноутбук"),
_mongo.updates().set("количество", 42)
)
старый = коллекция.findOneAndUpdate(
_mongo.filters().eq("название", "Ноутбук"),
_mongo.updates().set("количество", 42)
)
val старый = коллекция.findOneAndUpdate(
_mongo.filters().eq("название", "Ноутбук"),
_mongo.updates().set("количество", 42)
)
def старый = коллекция.findOneAndUpdate(
_mongo.filters().eq("название", "Ноутбук"),
_mongo.updates().set("количество", 42)
)
Замена документов
С помощью replaceOne() заменяет документ целиком (в отличие от обновлений, не может содержать операторы обновления):
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
коллекция.replaceOne(
_mongo.filters().eq("название", "Ноутбук"),
_val.map()
.set("название", "Ноутбук")
.set("количество", 50)
.set("цена", 150)
.set("категория", "избранное")
)
коллекция.replaceOne(
_mongo.filters().eq("название", "Ноутбук"),
_val.map()
.set("название", "Ноутбук")
.set("количество", 50)
.set("цена", 150)
.set("категория", "избранное")
)
коллекция.replaceOne(
_mongo.filters().eq("название", "Ноутбук"),
_val.map()
.set("название", "Ноутбук")
.set("количество", 50)
.set("цена", 150)
.set("категория", "избранное")
)
коллекция.replaceOne(
_mongo.filters().eq("название", "Ноутбук"),
_val.map()
.set("название", "Ноутбук")
.set("количество", 50)
.set("цена", 150)
.set("категория", "избранное")
)
коллекция.replaceOne(
_mongo.filters().eq("название", "Ноутбук"),
_val.map()
.set("название", "Ноутбук")
.set("количество", 50)
.set("цена", 150)
.set("категория", "избранное")
)
коллекция.replaceOne(
_mongo.filters().eq("название", "Ноутбук"),
_val.map()
.set("название", "Ноутбук")
.set("количество", 50)
.set("цена", 150)
.set("категория", "избранное")
)
Чтобы атомарно найти и заменить документ, вернув старый документ, используйте findOneAndReplace():
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const старый = коллекция.findOneAndReplace(
_mongo.filters().eq("название", "Ноутбук"),
_val.map()
.set("название", "Ноутбук")
.set("количество", 50)
)
const старый = коллекция.findOneAndReplace(
_mongo.filters().eq("название", "Ноутбук"),
_val.map()
.set("название", "Ноутбук")
.set("количество", 50)
)
старый = коллекция.findOneAndReplace(
_mongo.filters().eq("название", "Ноутбук"),
_val.map()
.set("название", "Ноутбук")
.set("количество", 50)
)
старый = коллекция.findOneAndReplace(
_mongo.filters().eq("название", "Ноутбук"),
_val.map()
.set("название", "Ноутбук")
.set("количество", 50)
)
val старый = коллекция.findOneAndReplace(
_mongo.filters().eq("название", "Ноутбук"),
_val.map()
.set("название", "Ноутбук")
.set("количество", 50)
)
def старый = коллекция.findOneAndReplace(
_mongo.filters().eq("название", "Ноутбук"),
_val.map()
.set("название", "Ноутбук")
.set("количество", 50)
)
Удаление документов
С помощью deleteOne() и deleteMany() удаляет документы, соответствующие фильтру:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
коллекция.deleteOne(
_mongo.filters().eq("название", "Ноутбук")
)
коллекция.deleteMany(
_mongo.filters().eq("категория", "неактивные")
)
коллекция.deleteOne(
_mongo.filters().eq("название", "Ноутбук")
)
коллекция.deleteMany(
_mongo.filters().eq("категория", "неактивные")
)
коллекция.deleteOne(
_mongo.filters().eq("название", "Ноутбук")
)
коллекция.deleteMany(
_mongo.filters().eq("категория", "неактивные")
)
коллекция.deleteOne(
_mongo.filters().eq("название", "Ноутбук")
)
коллекция.deleteMany(
_mongo.filters().eq("категория", "неактивные")
)
коллекция.deleteOne(
_mongo.filters().eq("название", "Ноутбук")
)
коллекция.deleteMany(
_mongo.filters().eq("категория", "неактивные")
)
коллекция.deleteOne(
_mongo.filters().eq("название", "Ноутбук")
)
коллекция.deleteMany(
_mongo.filters().eq("категория", "неактивные")
)
Чтобы атомарно найти и удалить документ, вернув удалённый документ, используйте findOneAndDelete():
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const старый = коллекция.findOneAndDelete(
_mongo.filters().eq("название", "Планшет")
)
const старый = коллекция.findOneAndDelete(
_mongo.filters().eq("название", "Планшет")
)
старый = коллекция.findOneAndDelete(
_mongo.filters().eq("название", "Планшет")
)
старый = коллекция.findOneAndDelete(
_mongo.filters().eq("название", "Планшет")
)
val старый = коллекция.findOneAndDelete(
_mongo.filters().eq("название", "Планшет")
)
def старый = коллекция.findOneAndDelete(
_mongo.filters().eq("название", "Планшет")
)
Чтобы удалить все документы коллекции, передайте пустой фильтр с помощью _mongo.valToDoc():
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
коллекция.deleteMany(_mongo.valToDoc(_val.map()))
коллекция.deleteMany(_mongo.valToDoc(_val.map()))
коллекция.deleteMany(_mongo.valToDoc(_val.map()))
коллекция.deleteMany(_mongo.valToDoc(_val.map()))
коллекция.deleteMany(_mongo.valToDoc(_val.map()))
коллекция.deleteMany(_mongo.valToDoc(_val.map()))
Подсчёт документов
С помощью countDocuments() получает количество документов в коллекции, при необходимости с фильтром. estimatedDocumentCount() работает быстрее, так как использует метаданные коллекции, но без фильтра:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const всего = коллекция.countDocuments()
const всего_основные = коллекция.countDocuments(
_mongo.filters().eq("категория", "компьютеры")
)
const оценочно = коллекция.estimatedDocumentCount()
const всего = коллекция.countDocuments()
const всего_основные = коллекция.countDocuments(
_mongo.filters().eq("категория", "компьютеры")
)
const оценочно = коллекция.estimatedDocumentCount()
всего = коллекция.countDocuments()
всего_основные = коллекция.countDocuments(
_mongo.filters().eq("категория", "компьютеры")
)
оценочно = коллекция.estimatedDocumentCount()
всего = коллекция.countDocuments()
всего_основные = коллекция.countDocuments(
_mongo.filters().eq("категория", "компьютеры")
)
оценочно = коллекция.estimatedDocumentCount()
val всего = коллекция.countDocuments()
val всего_основные = коллекция.countDocuments(
_mongo.filters().eq("категория", "компьютеры")
)
val оценочно = коллекция.estimatedDocumentCount()
def всего = коллекция.countDocuments()
def всего_основные = коллекция.countDocuments(
_mongo.filters().eq("категория", "компьютеры")
)
def оценочно = коллекция.estimatedDocumentCount()
Индексы
С помощью фабрики _mongo.indexes() создаются индексы для повышения производительности запросов. Чтобы создать индекс, достаточно передать спецификации в createIndex():
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
коллекция.createIndex(
_mongo.indexes().ascending("количество")
)
коллекция.createIndex(
_mongo.indexes().compoundIndex(
_mongo.indexes().descending("цена"),
_mongo.indexes().ascending("количество")
)
)
коллекция.createIndex(
_mongo.indexes().ascending("количество")
)
коллекция.createIndex(
_mongo.indexes().compoundIndex(
_mongo.indexes().descending("цена"),
_mongo.indexes().ascending("количество")
)
)
коллекция.createIndex(
_mongo.indexes().ascending("количество")
)
коллекция.createIndex(
_mongo.indexes().compoundIndex(
_mongo.indexes().descending("цена"),
_mongo.indexes().ascending("количество")
)
)
коллекция.createIndex(
_mongo.indexes().ascending("количество")
)
коллекция.createIndex(
_mongo.indexes().compoundIndex(
_mongo.indexes().descending("цена"),
_mongo.indexes().ascending("количество")
)
)
коллекция.createIndex(
_mongo.indexes().ascending("количество")
)
коллекция.createIndex(
_mongo.indexes().compoundIndex(
_mongo.indexes().descending("цена"),
_mongo.indexes().ascending("количество")
)
)
коллекция.createIndex(
_mongo.indexes().ascending("количество")
)
коллекция.createIndex(
_mongo.indexes().compoundIndex(
_mongo.indexes().descending("цена"),
_mongo.indexes().ascending("количество")
)
)
Можно указать MongoDB, какой индекс использовать в запросе, с помощью hint():
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const документы = коллекция.find().hint(
_mongo.valToDoc(
_val.map().set("количество", 1)
)
).all()
const документы = коллекция.find().hint(
_mongo.valToDoc(
_val.map().set("количество", 1)
)
).all()
документы = коллекция.find().hint(
_mongo.valToDoc(
_val.map().set("количество", 1)
)
).all()
документы = коллекция.find().hint(
_mongo.valToDoc(
_val.map().set("количество", 1)
)
).all()
val документы = коллекция.find().hint(
_mongo.valToDoc(
_val.map().set("количество", 1)
)
).all()
def документы = коллекция.find().hint(
_mongo.valToDoc(
_val.map().set("количество", 1)
)
).all()
С помощью min() и max() можно ограничить диапазон значений индекса, просматриваемых запросом:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const документы = коллекция.find()
.min(
_mongo.valToDoc(
_val.map().set("количество", 10)
)
)
.max(
_mongo.valToDoc(
_val.map().set("количество", 50)
)
)
.all()
const документы = коллекция.find()
.min(
_mongo.valToDoc(
_val.map().set("количество", 10)
)
)
.max(
_mongo.valToDoc(
_val.map().set("количество", 50)
)
)
.all()
документы = коллекция.find()
.min(
_mongo.valToDoc(
_val.map().set("количество", 10)
)
)
.max(
_mongo.valToDoc(
_val.map().set("количество", 50)
)
)
.all()
документы = коллекция.find()
.min(
_mongo.valToDoc(
_val.map().set("количество", 10)
)
)
.max(
_mongo.valToDoc(
_val.map().set("количество", 50)
)
)
.all()
val документы = коллекция.find()
.min(
_mongo.valToDoc(
_val.map().set("количество", 10)
)
)
.max(
_mongo.valToDoc(
_val.map().set("количество", 50)
)
)
.all()
def документы = коллекция.find()
.min(
_mongo.valToDoc(
_val.map().set("количество", 10)
)
)
.max(
_mongo.valToDoc(
_val.map().set("количество", 50)
)
)
.all()
Агрегации
Для более сложного анализа aggregate() позволяет выполнять конвейер агрегации, где каждый этап определяется фабрикой _mongo.aggregates(), а аккумуляторы — _mongo.accumulators().
Например, чтобы сгруппировать товары по категории и просуммировать цену в каждой группе:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const документы = коллекция.aggregate(
_mongo.aggregates().match(
_mongo.filters().eq("категория", "компьютеры")
),
_mongo.aggregates().group(
"$категория",
_mongo.accumulators().sum("итого", "$цена")
),
_mongo.aggregates().sort(
_mongo.sorts().descending("итого")
)
).all()
const документы = коллекция.aggregate(
_mongo.aggregates().match(
_mongo.filters().eq("категория", "компьютеры")
),
_mongo.aggregates().group(
"$категория",
_mongo.accumulators().sum("итого", "$цена")
),
_mongo.aggregates().sort(
_mongo.sorts().descending("итого")
)
).all()
документы = коллекция.aggregate(
_mongo.aggregates().match(
_mongo.filters().eq("категория", "компьютеры")
),
_mongo.aggregates().group(
"$категория",
_mongo.accumulators().sum("итого", "$цена")
),
_mongo.aggregates().sort(
_mongo.sorts().descending("итого")
)
).all()
документы = коллекция.aggregate(
_mongo.aggregates().match(
_mongo.filters().eq("категория", "компьютеры")
),
_mongo.aggregates().group(
"$категория",
_mongo.accumulators().sum("итого", "$цена")
),
_mongo.aggregates().sort(
_mongo.sorts().descending("итого")
)
).all()
val документы = коллекция.aggregate(
_mongo.aggregates().match(
_mongo.filters().eq("категория", "компьютеры")
),
_mongo.aggregates().group(
"$категория",
_mongo.accumulators().sum("итого", "$цена")
),
_mongo.aggregates().sort(
_mongo.sorts().descending("итого")
)
).all()
def документы = коллекция.aggregate(
_mongo.aggregates().match(
_mongo.filters().eq("категория", "компьютеры")
),
_mongo.aggregates().group(
"$категория",
_mongo.accumulators().sum("итого", "$цена")
),
_mongo.aggregates().sort(
_mongo.sorts().descending("итого")
)
).all()
Доступны следующие этапы агрегации:
| Этап | Описание |
|---|---|
match(фильтр) | Выбирает только документы, соответствующие фильтру. |
group("$поле", аккумуляторы) | Группирует документы по полю и применяет аккумуляторы. |
project(проекция) | Добавляет, удаляет или изменяет поля в документах. |
sort(сортировка) | Сортирует документы. |
limit(n) | Ограничивает первыми n документами. |
skip(n) | Пропускает первые n документов. |
count() | Считает количество документов. |
lookup("коллекция", "локальноеПоле", "внешнееПоле", "как") | Выполняет join с другой коллекцией. |
И наиболее часто используемые аккумуляторы:
| Аккумулятор | Описание |
|---|---|
sum("поле", "$выражение") | Сумма значений. |
avg("поле", "$выражение") | Среднее значений. |
min("поле", "$выражение") | Минимальное значение. |
max("поле", "$выражение") | Максимальное значение. |
first("поле", "$выражение") | Значение первого документа. |
last("поле", "$выражение") | Значение последнего документа. |
top("поле", сортировка, "$выражение") | Верхнее значение согласно сортировке. |
bottom("поле", сортировка, "$выражение") | Нижнее значение согласно сортировке. |
В аккумуляторах выражение с префиксом
$ссылается на поле входного документа, например"$цена".
Преобразование между Values и BSON
Иногда необходимо преобразовывать объекты _val Netuno в документы BSON MongoDB и обратно:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const документ = _mongo.valToDoc(
_val.map().set("название", "Ноутбук")
)
const значения = _mongo.docToVal(документ)
const документ = _mongo.valToDoc(
_val.map().set("название", "Ноутбук")
)
const значения = _mongo.docToVal(документ)
документ = _mongo.valToDoc(
_val.map().set("название", "Ноутбук")
)
значения = _mongo.docToVal(документ)
документ = _mongo.valToDoc(
_val.map().set("название", "Ноутбук")
)
значения = _mongo.docToVal(документ)
val документ = _mongo.valToDoc(
_val.map().set("название", "Ноутбук")
)
val значения = _mongo.docToVal(документ)
def документ = _mongo.valToDoc(
_val.map().set("название", "Ноутбук")
)
def значения = _mongo.docToVal(документ)
Операции с опциями
Фабрики *Options() ресурса _mongo возвращают стандартные объекты опций драйвера MongoDB, и их методы можно вызывать цепочкой напрямую. Например, upsert(true) вставляет документ, когда фильтр не соответствует ни одному существующему документу:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const старый = коллекция.findOneAndUpdate(
_mongo.filters().eq("название", "Монитор"),
_mongo.updates().set("количество", 8),
_mongo.findOneAndUpdateOptions().upsert(true)
)
const старый = коллекция.findOneAndUpdate(
_mongo.filters().eq("название", "Монитор"),
_mongo.updates().set("количество", 8),
_mongo.findOneAndUpdateOptions().upsert(true)
)
старый = коллекция.findOneAndUpdate(
_mongo.filters().eq("название", "Монитор"),
_mongo.updates().set("количество", 8),
_mongo.findOneAndUpdateOptions().upsert(true)
)
старый = коллекция.findOneAndUpdate(
_mongo.filters().eq("название", "Монитор"),
_mongo.updates().set("количество", 8),
_mongo.findOneAndUpdateOptions().upsert(true)
)
val старый = коллекция.findOneAndUpdate(
_mongo.filters().eq("название", "Монитор"),
_mongo.updates().set("количество", 8),
_mongo.findOneAndUpdateOptions().upsert(true)
)
def старый = коллекция.findOneAndUpdate(
_mongo.filters().eq("название", "Монитор"),
_mongo.updates().set("количество", 8),
_mongo.findOneAndUpdateOptions().upsert(true)
)
Когда документ вставляется, findOneAndUpdate() возвращает null.
Доступные фабрики опций: insertOneOptions(), insertManyOptions(), updateOptions(), findOneAndUpdateOptions(), replaceOptions(), findOneAndReplaceOptions(), deleteOptions(), findOneAndDeleteOptions(), countOptions(), estimatedDocumentCountOptions(), dropCollectionOptions() и textSearchOptions().
Закрытие подключения
По завершении рекомендуется закрыть подключение к MongoDB:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_mongo.close()
_mongo.close()
_mongo.close()
_mongo.close()
_mongo.close()
_mongo.close()
Заключение
С ресурсом _mongo Netuno предоставляет low-code- и полиглотную абстракцию над официальным клиентом MongoDB для Java, позволяя работать с документами, фильтрами, сортировками, проекциями, обновлениями, индексами и агрегациями в JavaScript, Python, Ruby, Kotlin и Groovy.
Для получения более подробной информации обо всех доступных методах обратитесь к документации ресурса _mongo и класса MongoCollection.
Удачной разработки!