Mongoose is one of the fundamental tools for manipulating data for a Node.js/MongoDB backend. In this article we’ll be looking into some of the basic ways of using Mongoose and even using it with the MongoDB Atlas remote database.
Mongoose是为Node.js / MongoDB后端处理数据的基本工具之一。 在本文中,我们将研究使用Mongoose甚至与MongoDB Atlas远程数据库一起使用的一些基本方法。
先决条件 (Prerequisites)
Since we’ll be using Express
to set up a basic server, I would recommend checking out this article on express and the official Express docs if you’re not very comfortable with it just yet.
由于我们将使用Express
来设置基本服务器,因此,如果您对Express和正式的Express文档还不太满意,建议您参考这篇文章 。
We’ll also be setting up a very basic REST Api without any authentication, you can learn a bit more about that here, but the routing will be asynchronous and we’ll be using async/await
functions, which you can freshen up on here.
我们还将建立一个没有任何身份验证的非常基本的REST Api,您可以在此处了解更多信息 ,但是路由将是异步的,我们将使用async/await
函数,您可以在此处进行更新。 。
安装 (Installation)
Of course, we’ll also need to have express
installed to set up our server.
当然,我们还需要安装express
来设置服务器。
$ npm i express mongoose
档案设定 (File Setup)
We’ll only need three files and two folders to get started. This folder structure works well for the sake of organization if you want to add more to your API in the future:
我们只需要三个文件和两个文件夹即可上手。 如果您以后想在API中添加更多内容,则该文件夹结构可以很好地用于组织工作:
models 📂
FoodModel.js
routes 📂
FoodRoutes.js
server.js
MongoDB Atlas安装 (MongoDB Atlas Setup)
We’ll need to get setup with MongoDB Atlas. Here’s a summary of the steps to get started:
我们需要使用MongoDB Atlas进行设置。 以下是入门步骤的摘要:
- Setup an account 设置一个帐户
Hit
Build a Cluster
点击
Build a Cluster
Go to Database Access and hit
Add New User
. Add a username and password, if you autogenerate a password make sure you copy it, we’ll need it later.转到数据库访问,然后单击
Add New User
。 添加用户名和密码,如果您自动生成密码,请确保将其复制出来,稍后我们将需要它。Go to Network Access, hit
Add IP Address
, and hitAdd Current IP Address
, then confirm.转到网络访问,点击
Add IP Address
,然后点击Add Current IP Address
,然后确认。Go to
Clusters
, if your cluster build is done then hitConnect
,Connect Your Application
, and copy the line of code it gives you转到
Clusters
,如果集群构建完成,则单击Connect
,Connect Your Application
(Connect Your Application
,并复制它给您的代码行
Everything else with MongoDB Atlas will be handled on our end with in Node.js.
MongoDB Atlas的其他所有功能都将在Node.js中处理。
邮递员设置 (Postman Setup)
We’ll be using Postman to help manage our requests for us. Once you get it downloaded and set up, create a new collection called whatever you want (mine will be called Gator Diner). On the bottom right of the new collection, there are three little dots that give you an ‘Add Request’ option. Every time we make a new API endpoint we’ll be setting up another request for it. This will help you manage everything so you don’t have to copy/paste HTTP requests everywhere.
我们将使用Postman帮助管理对我们的要求。 下载并设置好它之后,创建一个新集合,无论您想要什么(我的都会称为Gator Diner )。 在新集合的右下角,有三个小点,为您提供“添加请求”选项。 每次创建新的API端点时,我们都会为其设置另一个请求。 这将帮助您管理所有内容,因此您不必在各处复制/粘贴HTTP请求。
服务器设置 (Server Setup)
Here we’ll set up our basic Express server on port 3000, connect to our Atlas database, and import our future routes. mongoose.connect()
will take the line of code we copied from Atlas and an object of configuration options (the only option we’ll be using is useNewUrlParser
, which will just get rid of an annoying terminal error we get saying that the default is deprecated, this doesn’t change the behavior or the usage).
在这里,我们将在端口3000上设置基本的Express服务器,连接到Atlas数据库,并导入将来的路由。 mongoose.connect()
将使用我们从Atlas复制的代码行和一个配置选项对象(我们将使用的唯一选项是useNewUrlParser
,它将摆脱一个令人讨厌的终端错误,我们说默认是不推荐使用,则不会更改行为或用法)。
In the MongoDB Atlas code provided there is a section like UserName:<password>
, replace with the username and whatever password you set up in Atlas (make sure to remove the greater/less than signs).
在提供的MongoDB Atlas代码中,有一个类似于UserName:<password>
,替换为用户名和您在Atlas中设置的任何密码(请确保删除大于/小于符号)。
const express = require('express');
const mongoose = require('mongoose');
const foodRouter = require('./routes/foodRoutes.js');
const app = express();
app.use(express.json()); // Make sure it comes back as json
mongoose.connect('mongodb+srv://UserName:<password>@cluster0-8vkls.mongodb.net/test?retryWrites=true&w=majority', {
useNewUrlParser: true
});
app.use(foodRouter);
app.listen(3000, () => { console.log('Server is running...') });
There we go, now we’re all hooked up to our backend and we can start actually learning mongoose.
我们走了,现在我们都已经连接到后端,我们可以开始实际学习猫鼬了。
模式 (Schemas)
First we need to have a pattern to structure our data onto, and these patterns are referred to as schemas. Schemas allow us to decide exactly what data we want, and what options we want the data to have as an object.
首先,我们需要一种模式来将数据结构化,这些模式称为模式。 模式使我们能够准确地决定我们想要什么数据,以及我们希望数据作为对象具有哪些选项。
With that basic pattern in place we’ll use the mongoose.model
method to make it usable with actual data and export it as a variable we can use in foodRoutes.js
.
有了该基本模式后,我们将使用mongoose.model
方法使其可用于实际数据,并将其导出为可在foodRoutes.js
使用的变量。
选件 (Options)
type
Sets whether it is aString
,Number
,Date
,Boolean
,Array
, or aMap
(an object).type
设置它是String
,Number
,Date
,Boolean
,Array
还是Map
(一个对象)。required
(Boolean) Return an error if not provided.required
(布尔值),如果未提供,则返回错误。trim
(Boolean) Removes any extra whitespace.trim
(布尔值)删除所有多余的空格。uppercase
(Boolean) Converts to uppercase.uppercase
(布尔)转换为大写。lowercase
(Boolean) Converts to lowercase.lowercase
(布尔)转换为小写。validate
Sets a function to determine if the result is acceptable.validate
设置一个函数来确定结果是否可接受。default
Sets the default if no data is given.default
如果未提供数据,则设置默认值。
const mongoose = require('mongoose');
const FoodSchema = new mongoose.Schema({
name: {
type: String,
required: true,
trim: true,
lowercase: true
},
calories: {
type: Number,
default: 0,
validate(value) {
if (value < 0) throw new Error("Negative calories aren't real.");
}
},
});
const Food = mongoose.model("Food", FoodSchema);
module.exports = Food;
查询功能 (Query Functions)
While there are many querying functions available, which you can find here, here are the ones we’ll be using in this instance:
尽管有许多查询功能可用,但您可以在此处找到 ,以下是我们在此实例中将要使用的功能:
find()
Returns all objects with matching parameters so.find({ name: fish })
would return every object named fish and an empty object will return everything.find()
返回所有具有匹配参数的对象,因此.find({ name: fish })
将返回每个名为fish的对象,而一个空对象将返回所有内容。save()
Save it to our Atlas database.save()
将其保存到我们的Atlas数据库。findByIdAndDelete()
Takes the objects id and removes from the database.findByIdAndDelete()
获取对象ID并从数据库中删除。findByIdAndUpdate
Takes the objects id and an object to replace it with.findByIdAndUpdate
获取对象ID和一个替换它的对象。deleteOne()
anddeleteMany()
Removes the first or all items from the database.deleteOne()
和deleteMany()
从数据库中删除第一个或所有项目。
阅读全部 (Read All)
Once we have our data model set up we can start setting up basic routes to use it.
一旦我们建立了数据模型,我们就可以开始建立使用它的基本路线。
We’ll start by getting all foods in the database, which should just be an empty array right now. Since Mongoose functions are asynchronous, we’ll be using async/await
.
我们将从获取数据库中的所有食物开始,现在它应该只是一个空数组。 由于Mongoose函数是异步的,因此我们将使用async/await
。
Once we have the data we’ll use a try/catch block to send it back to and so that we can see that things are working using Postman.
有了数据后,我们将使用try / catch块将其发送回,以便我们可以看到使用Postman可以正常工作。
const express = require('express');
const foodModel = require('../models/food');
const app = express();
app.get('/foods', async (req, res) => {
const foods = await foodModel.find({});
try {
res.send(foods);
} catch (err) {
res.status(500).send(err);
}
});
module.exports = app
In Postman, we’ll create a new Get All request, set the url to localhost:3000/foods
, and hit send. It should make our HTTP GET request for us and return our empty array.
在Postman中,我们将创建一个新的Get All请求,将URL设置为localhost:3000/foods
,然后单击send。 它应该为我们发出HTTP GET请求并返回我们的空数组。
创造 (Create)
This time we’ll be setting up a post request to '/food'
and we’ll create a new food object with our model and pass it the request data from Postman.
这次,我们将向'/food'
设置发布请求,并使用模型创建一个新的food对象,并将Postman的请求数据传递给该对象。
Once we have a model with data in place, we can use .save()
to save it to our database.
建立具有适当数据的模型后,可以使用.save()
将其保存到数据库中。
app.post('/food', async (req, res) => {
const food = new foodModel(req.body);
try {
await food.save();
res.send(food);
} catch (err) {
res.status(500).send(err);
}
});
In Postman we’ll make another request called Add New, give it the URL like before to localhost:3000/food
, and change it from a GET to a POST request.
在Postman中,我们将发出另一个名为Add New的请求,像以前一样给它提供URL到localhost:3000/food
,并将其从GET更改为POST请求。
Over in Body
, select raw and JSON (application/json) from the drop down. Here we can add whatever new food item we want to save to our database.
在Body
,从下拉列表中选择raw和JSON(application / json) 。 在这里,我们可以将要保存的任何新食品添加到数据库中。
{
"name": "snails",
"calories": "100"
}
If you run the Get All request again, our once empty array should now contain this object.
如果再次运行“ 获取全部”请求,则我们曾经为空的数组现在应包含该对象。
删除 (Delete)
Every object created with Mongoose is given its own _id
, and we can use this to target specific items with a DELETE
request. We can use the .findByIdAndDelete()
method to easily remove it from the database, it obviously just needs the id, which is stored on our request object.
每个用Mongoose创建的对象都被赋予了自己的_id
,我们可以使用它通过DELETE
请求来定位特定的项目。 我们可以使用.findByIdAndDelete()
方法轻松地将其从数据库中删除,显然,它只需要存储在请求对象中的id。
app.delete('/food/:id', async (req, res) => {
try {
const food = await foodModel.findByIdAndDelete(req.params.id)
if (!food) res.status(404).send("No item found")
res.status(200).send()
} catch (err) {
res.status(500).send(err)
}
})
In Postman we can use the Get All request to get the id of one of our items, and add that to the end of our url in our new Remove request, it’ll look something like localhost:3000/food/5d1f6c3e4b0b88fb1d257237
.
在Postman中,我们可以使用Get All请求来获取其中一项的ID,并将其添加到新的Remove请求中的URL末尾,其外观类似于localhost:3000/food/5d1f6c3e4b0b88fb1d257237
。
Run Get All again and it should be gone.
再次运行“全部获取” ,它应该消失了。
更新资料 (Update)
Just like with the delete request, we’ll be using the _id
to target the correct item. .findByIdAndUpdate()
just takes the target’s id, and the request data you want to replace it with.
就像删除请求一样,我们将使用_id
定位正确的项目。 .findByIdAndUpdate()
仅获取目标的ID,以及您要替换为目标的请求数据。
app.patch('/food/:id', async (req, res) => {
try {
await foodModel.findByIdAndUpdate(req.params.id, req.body)
await foodModel.save()
res.send(food)
} catch (err) {
res.status(500).send(err)
}
})
结论 (Conclusion)
With Mongoose methods we can quickly make and manage our backend data in a breeze. While there’s still much more to learn, hopefully this little introduction will help give you a brief insight into Mongoose and help you decide if it’s the right tool for you and your future projects.
使用Mongoose方法,我们可以轻而易举地快速制作和管理后端数据。 尽管还有更多的东西要学习,但希望这篇简短的介绍将帮助您简要了解Mongoose,并帮助您确定它是否适合您和您的未来项目。
翻译自: https://www.digitalocean.com/community/tutorials/nodejs-crud-operations-mongoose-mongodb-atlas