Рассмотрим, как выполнять основные операции с данными в Mongoose.
В прошлых темах было в общих чертах описано создание и добавление объектов в Mongoose. В частности, у объекта модели мы можем вызвать метод save():
const mongoose = require("mongoose"); const Schema = mongoose.Schema; const userScheme = new Schema({ name: String, age: Number }); const User = mongoose.model("User", userScheme); async function main() { await mongoose.connect("mongodb://127.0.0.1:27017/usersdb"); const tom = new User({name: "Tom", age: 34}); // добавляем объект в БД await tom.save(); console.log(tom); } main().catch(console.log).finally(async()=>await mongoose.disconnect());
Но кроме этого метода также можно использовать метод User.create():
const mongoose = require("mongoose"); const Schema = mongoose.Schema; const userScheme = new Schema({ name: String, age: Number }); const User = mongoose.model("User", userScheme); async function main() { await mongoose.connect("mongodb://127.0.0.1:27017/usersdb"); // добавляем объект в БД const user = await User.create({name: "Sam", age: 28}) console.log(user); } main().catch(console.log).finally(async()=>await mongoose.disconnect());
В качестве параметра метод User.create()
принимает сохраняемый объект и возвращает сохраненный объект.
Для получения данных можно использовать целый набор методов:
find: возвращает все объекты, которые соответствуют критерию фильтрации
findById: возвращает один объект по значению поля _id
findOne: возвращает один объект, который соответствует критерию фильтрации
Метод find() в качестве первого параметра принимает критерий фильтрации, а второй параметр - функция обратного вызова, в которую передаются полученные из бд документы:
const mongoose = require("mongoose"); const Schema = mongoose.Schema; const userScheme = new Schema({name: String, age: Number}); const User = mongoose.model("User", userScheme); async function main() { await mongoose.connect("mongodb://127.0.0.1:27017/usersdb"); // получаем все объекты из БД const users = await User.find({}); console.log(users); } main().catch(console.log).finally(async()=>await mongoose.disconnect());
Если в качестве критерия фильтрации передаются пустые фигурные скобки ({}), то возвращаются все объекты:
[ { _id: new ObjectId("6377c17b71c0bd75cec4d488"), name: 'Bill', age: 41, __v: 0 }, { _id: new ObjectId("6377c7a46fa33e19ac7a7c41"), name: 'Tom', age: 34, __v: 0 }, { _id: new ObjectId("6377ce352461051cdc78252a"), name: 'Sam', age: 28, __v: 0 } ]
Изменим код для получения только тех пользователей, у которых имя - Tom:
const users = await User.find({name: "Tom"});
Метод findOne() работает аналогично методу find, только возвращает один объект:
const user = await User.findOne({name: "Bill"});
И метод findById() возвращает документ с определенным идентификатором:
const id = "6377c7a46fa33e19ac7a7c41"; const user = await User.findById(id);
Для удаления применяется метод deleteOne() (удаляет один объект) и deleteMany() (удаляет все объекты, которые соответствуют критери.). В эти методы передается критерий фильтрации документов на удаление. Например, удалим всех пользователей, у которых возраст равен 41:
const mongoose = require("mongoose"); const Schema = mongoose.Schema; const userScheme = new Schema({name: String, age: Number}); const User = mongoose.model("User", userScheme); async function main() { await mongoose.connect("mongodb://127.0.0.1:27017/usersdb"); // удаляем все объекты из БД, у которых age=41 const result = await User.deleteMany({age:41}); console.log(result); } main().catch(console.log).finally(async()=>await mongoose.disconnect());
Метод User.deleteMany()
возвращает объект, который содержит информацию об операции удаления:
{ acknowledged: true, deletedCount: 1 }
Так, свойства deletedCount
хранит количество удаленных строк
Применение метода deleteOne() для удаления одного документа будет аналогичным:
const result = await User.deleteOne({name:"Tom"}) console.log(result); // { acknowledged: true, deletedCount: 1 }
Также для удаления одного документа можно использовать метод findOneAndDelete():
const user = await User.findOneAndDelete({name:"Sam"}) console.log(user);
В качестве результата он возвращает удаленный документ.
{ _id: new ObjectId("6377bca2d16bfca92631cc10"), name: 'Sam', age: 28 }
И частная разновидность этого метода - удаление по полю _id в виде метода findByIdAndDelete():
const id = "6377c72806fb915eb6621ffd"; const user = await User.findByIdAndDelete(id) console.log(user);
Для обновления данных в модели предусмотрены методы updateOne() и updateMany(). Первый метод обновляет один документ, который соответствует критерию, а второй метод обновляет все документы, которые соответствую критерию выборки:
const mongoose = require("mongoose"); const Schema = mongoose.Schema; const userScheme = new Schema({name: String, age: Number}); const User = mongoose.model("User", userScheme); async function main() { await mongoose.connect("mongodb://127.0.0.1:27017/usersdb"); // У всех документов изменяем значение поля name с "Tom" на "Tom Smith" const result = await User.updateOne({name: "Tom"}, {name: "Tom Smith"}) console.log(result); } main().catch(console.log).finally(async()=>await mongoose.disconnect());
Первый параметр метода - критерий фильтрации. В данном случае мы находим всех пользователей, у которых имя "Tom". А второй параметр описывает, что и как надо изменить. То есть здесь мы меняем имя на "Tom Smith". Возвращает метод результат операции обновления:
{ acknowledged: true, modifiedCount: 1, upsertedId: null, upsertedCount: 0, matchedCount: 1 }
Аналогично работает метод updateMany
.
Нередко для обновления используется фильтрация по _id. И на этот случай мы можем использовать метод findByIdAndUpdate():
const id = "6377ce352461051cdc78252a"; const user = await User.findByIdAndUpdate(id, {name: "Sam", age: 25}); console.log("Обновленный объект", user);
Первый параметр метода - значения для поля _id у обновляемого документа, а второй - набор новых значений для полей объекта. Результатом метода является обновленный документ:
Обновленный объект { _id: new ObjectId("6377ce352461051cdc78252a"), name: 'Sam', age: 28, __v: 0 }
Но по умолчанию передается старое состояние документа. Если же нам надо получить документ уже в измененном состоянии, то в метод findByIdAndUpdate
необходимо передать в качестве третьего параметра объект {new: true}
(при значении false возвращается старая копия):
const id = "6377ce352461051cdc78252a"; const user = await User.findByIdAndUpdate(id, {name: "Mike", age: 21}, {new: true}); console.log("Обновленный объект", user);
Если нам необходимо обновить и возвратить обновленный документ не только по id, а вообще по любому критерию, то можно использовать метод findOneAndUpdate:
const user = await User.findOneAndUpdate({name: "Mike"}, {name: "Alex", age:24}, {new: true}); console.log("Обновленный объект", user);
Первый параметр представляет критерий выборки. Второй параметр представляет обновленные значения документа. Третий параметр указывает,
что мы хотим возвратить вариант документа именно после обновления - {new: true}
. Результат метода - обновленный документ.