Criando uma aplicação CRUD em Mongoose com Node.js
Vamos examinar como realizar as operações básicas de dados em Mongoose.
Criando Documentos
Em tópicos anteriores, descrevemos de forma geral como criar e adicionar objetos no Mongoose. Especificamente, podemos chamar o método save() no objeto do modelo:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const userSchema = new Schema({
name: String,
age: Number,
});
const User = mongoose.model("User", userSchema);
async function main() {
await mongoose.connect("mongodb://127.0.0.1:27017/usersdb");
const tom = new User({ name: "Tom", age: 34 });
// adicionando objeto ao banco de dados
await tom.save();
console.log(tom);
}
main()
.catch(console.log)
.finally(async () => await mongoose.disconnect());Além desse método, também podemos usar o método User.create():
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const userSchema = new Schema({
name: String,
age: Number,
});
const User = mongoose.model("User", userSchema);
async function main() {
await mongoose.connect("mongodb://127.0.0.1:27017/usersdb");
// adicionando objeto ao banco de dados
const user = await User.create({ name: "Sam", age: 28 });
console.log(user);
}
main()
.catch(console.log)
.finally(async () => await mongoose.disconnect());O método User.create() recebe o objeto a ser salvo como parâmetro e retorna o objeto salvo.
Obtendo Dados
Para obter dados, podemos usar uma série de métodos:
find: retorna todos os objetos que correspondem ao critério de filtro.findById: retorna um objeto pelo valor do campo_id.findOne: retorna um objeto que corresponde ao critério de filtro.
O método find() aceita como primeiro parâmetro o critério de filtro e, como segundo parâmetro, uma função de callback para os documentos obtidos do banco de dados:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const userSchema = new Schema({ name: String, age: Number });
const User = mongoose.model("User", userSchema);
async function main() {
await mongoose.connect("mongodb://127.0.0.1:27017/usersdb");
// obtendo todos os objetos do banco de dados
const users = await User.find({});
console.log(users);
}
main()
.catch(console.log)
.finally(async () => await mongoose.disconnect());Se o critério de filtro for um objeto vazio ({}), todos os objetos serão retornados:
[
{
_id: "6377c17b71c0bd75cec4d488",
name: "Bill",
age: 41,
__v: 0,
},
{
_id: "6377c7a46fa33e19ac7a7c41",
name: "Tom",
age: 34,
__v: 0,
},
{
_id: "6377ce352461051cdc78252a",
name: "Sam",
age: 28,
__v: 0,
},
];Vamos alterar o código para obter apenas os usuários cujo nome seja "Tom":
const users = await User.find({ name: "Tom" });O método findOne() funciona de maneira semelhante ao método find, mas retorna um único objeto:
const user = await User.findOne({ name: "Bill" });E o método findById() retorna o documento com um identificador específico:
const id = "6377c7a46fa33e19ac7a7c41";
const user = await User.findById(id);Removendo Dados
Para remoção, usamos os métodos deleteOne() (remove um objeto) e deleteMany() (remove todos os objetos que correspondem ao critério). Esses métodos aceitam um critério de filtro dos documentos a serem removidos. Por exemplo, vamos remover todos os usuários com idade igual a 41:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const userSchema = new Schema({ name: String, age: Number });
const User = mongoose.model("User", userSchema);
async function main() {
await mongoose.connect("mongodb://127.0.0.1:27017/usersdb");
// removendo todos os objetos do banco de dados com age=41
const result = await User.deleteMany({ age: 41 });
console.log(result);
}
main()
.catch(console.log)
.finally(async () => await mongoose.disconnect());O método User.deleteMany() retorna um objeto contendo informações sobre a operação de remoção:
{ "acknowledged": true, "deletedCount": 1 }O método deleteOne() para remover um único documento é semelhante:
const result = await User.deleteOne({ name: "Tom" });
console.log(result); // { "acknowledged": true, "deletedCount": 1 }Para remover um único documento, também podemos usar o método findOneAndDelete():
const user = await User.findOneAndDelete({ name: "Sam" });
console.log(user);Esse método retorna o documento removido:
{ "_id": "6377bca2d16bfca92631cc10", "name": "Sam", "age": 28 }A versão específica desse método para remoção pelo campo _id é o método findByIdAndDelete():
const id = "6377c72806fb915eb6621ffd";
const user = await User.findByIdAndDelete(id);
console.log(user);Atualizando Dados
Para atualizar dados no modelo, utilizamos os métodos updateOne() e updateMany(). O primeiro método atualiza um documento que corresponde ao critério, enquanto o segundo atualiza todos os documentos que correspondem ao critério de seleção:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const userSchema = new Schema({ name: String, age: Number });
const User = mongoose.model("User", userSchema);
async function main() {
await mongoose.connect("mongodb://127.0.0.1:27017/usersdb");
// Alterando o valor do campo name de "Tom" para "Tom Smith" em todos os documentos
const result = await User.updateOne({ name: "Tom" }, { name: "Tom Smith" });
console.log(result);
}
main()
.catch(console.log)
.finally(async () => await mongoose.disconnect());O primeiro parâmetro do método é o critério de filtro. Nesse caso, encontramos todos os usuários com nome "Tom". O segundo parâmetro descreve as alterações a serem feitas. Aqui, estamos mudando o nome para "Tom Smith". O método retorna o resultado da operação de atualização:
{
"acknowledged": true,
"modifiedCount": 1,
"upsertedId": null,
"upsertedCount": 0,
"matchedCount": 1
}O método updateMany funciona de maneira semelhante.
Atualizando pelo ID
Frequentemente, usamos a filtro pelo _id para atualizações. Para isso, podemos usar o método findByIdAndUpdate():
const id = "6377ce352461051cdc78252a";
const user = await User.findByIdAndUpdate(id, { name: "Sam", age: 25 });
console.log(user);O primeiro parâmetro é o valor do campo _id do documento a ser atualizado, e o segundo é um conjunto de novos valores para os campos do objeto. O resultado do método é o documento atualizado:
{
"_id": "6377ce352461051cdc78252a",
"name": "Sam",
"age": 28,
"__v": 0
}Por padrão, é retornado o estado antigo do documento. Se precisarmos do documento no estado atualizado, passamos um terceiro parâmetro ao método findByIdAndUpdate, com {new: true} (com valor false, a cópia antiga é retornada):
const id = "6377ce352461051cdc78252a";
const user = await User.findByIdAndUpdate(id, { name: "Mike", age: 21 }, { new: true });
console.log("Objeto atualizado", user);Se precisamos atualizar e retornar o documento atualizado não apenas pelo ID, mas por qualquer critério, podemos usar o método findOneAndUpdate:
const user = await User.findOneAndUpdate({ name: "Mike" }, { name: "Alex", age: 24 }, { new: true });
console.log("Objeto atualizado", user);O primeiro parâmetro representa o critério de seleção. O segundo parâmetro representa os valores atualizados do documento. O terceiro parâmetro indica que queremos retornar a versão do documento após a atualização, {new: true}. O resultado do método é o documento atualizado.