设置 Mongoose 模式进行身份验证后,如何使用 Mongodb 查询数据库?
Posted
技术标签:
【中文标题】设置 Mongoose 模式进行身份验证后,如何使用 Mongodb 查询数据库?【英文标题】:How do I query the database using Mongodb after I set up a Mongoose schema for authentication? 【发布时间】:2021-05-31 01:50:34 【问题描述】:我成功地为我的应用程序设置了身份验证,这是一个 node.js (Express) 应用程序。我使用了 Passport-local,也使用了 Mongoose 模式。
文件夹结构是这样的:
app
- app.js
- config
- auth.js
- keys.js
- passport.js
- models
- User.js
- node_modules
- package-lock.json
- package.json
- routes
- index.js
- users.js
“models”文件夹内是 User.js 文件,它包含以下架构:
const mongoose=require("mongoose");
const UserSchema = new mongoose.Schema(
username:
type: String,
required: true,
min: 4,
max: 255
,
email:
type: String,
required: true,
min: 6,
max: 255
,
password:
type: String,
required: true,
min: 6,
max: 1024
,
group:
type: Number
,
score:
type: Number
,
date:
type: Date,
default: Date.now
);
const User = mongoose.model("User", UserSchema);
module.exports = User;
app.js(主文件)包含以下代码。顺便说一句,我并没有展示所有内容。连接字符串在 keys.js 文件中。
const mongoose=require("mongoose");
const db = require('./config/keys').mongoURI;
const app = express();
mongoose
.connect(
db,
useNewUrlParser: true ,useUnifiedTopology: true
)
.then(() => console.log('MongoDB Connected'))
.catch(err => console.log(err));
对于不需要数据库的操作,比如打开一个.ejs文件,使用“GET”是没有问题的。我能做到。
我可以注册并登录一个用户,该用户出现在名为“users”的 Mongodb 集合中,并显示了正确的字段。在我使用 Web 应用程序中的注册和登录表单添加用户之前,此集合不存在。
现在我想在数据库中使用相同的集合(“用户”)来测试 CRUD 操作。所以我尝试了这个:
app.get("/leaderboard", function(req, res)
db.collection("users")
.find(, projection: _id: 0, username: 1, score: 1 )
.sort(score:-1)
.limit(1)
.toArray(function(err, result)
if (err)
res.send( status: false, msg: "failed to retrieve players" );
console.log(Array.from(result));
res.send( status: true, msg: result );
)
);
在向 api 添加身份验证之前,我能够毫无问题地获得此查询的结果以及对数据库的所有其他查询。
虽然集合名称不同,但我为数据库使用了不同的连接脚本。下面是这样的。 MONGO_URI 作为字符串存储在 dotenv 文件中。我也没有猫鼬模式。我只有 index.js 文件;没有其他文件夹。
// Database Connection Info
const MongoClient = require('mongodb').MongoClient;
const uri = process.env.MONGO_URI;
let db;
// Connect to the database with uri
(async () =>
let client = await MongoClient.connect(
uri,
useNewUrlParser: true, useUnifiedTopology: true
);
db = client.db('name');
app.listen(PORT, async function()
console.log('Listening on Port $PORT');
if (db)
console.log('Database is Connected!');
);
)();
过去,我使用异步函数来获取排行榜结果。它使用不同的集合(“myCollection”)但使用相同的数据库。
app.get("/leaderboard", async function(req, res)
try
await db.collection("myCollection")
.find(, projection: _id: 0, username: 1, score: 1 )
.sort(score:-1)
.limit(1)
.toArray(function(err, result)
if (err)
res.send( status: false, msg: "failed to retrieve players" );
console.log(Array.from(result));
res.send( status: true, msg: result );
)
catch(err) console.log("It failed")
);
但即使在我添加身份验证和添加 Mongoose 模型之前,上述方法运行良好,但我现在无法显示排行榜结果。在终端中输入“节点应用程序”后,我在控制台上收到“MongoDB 已连接”消息,但没有收到任何错误消息。这是在我尝试获取排行榜之前。
我尝试获取排行榜后在控制台上收到的错误消息是:
TypeError: db.collection is not a function
我也试过下面的脚本没有成功:
app.get("/leaderboard", function(req, res)
User
.find(, projection: _id: 0, username: 1, score: 1 )
.sort(score:-1)
.limit(1)
.toArray(function(err, result)
if (err)
res.send( status: false, msg: "failed to retrieve players" );
console.log(Array.from(result));
res.send( status: true, msg: result );
)
);
我想对数据库查询使用异步函数,但找不到适用于我的新连接方式的连接脚本:“mongoose.connect”。
我觉得我必须使用“mongoose.connect”连接方式而不是“const uri = process.env.MONGO_URI;”方式,因为我使用猫鼬模式进行身份验证。这个模式会自动创建注册用户的集合。 (我没有任何真正的用户;我正在使用假用户配置文件来测试该过程。)我还假设 mongoose 和 mongodb 之间存在差异。
如果我可以使用旧方法,那将是最好的,因为我可以在脚本中使用 async/await。但是,主要问题是我根本没有得到任何结果,只有错误消息,尽管在添加身份验证之前我能够执行许多涉及数据库的操作。
【问题讨论】:
【参考方案1】:我可以通过像这样编写到 mongodb 的连接来解决这个问题:
const MONGO_URI="mongodb+srv://<username>:<password>@<insert string><database>?retryWrites=true&w=majority";
mongoose
.connect(MONGO_URI, useNewUrlParser: true, useUnifiedTopology: true)
.then(console.log(`MongoDB connected $MONGO_URI`))
.catch(err=>console.log(err));
然后我这样写查询:
app.get("/leaderboard", async function(req, res)
const client = await mongoose.connect(MONGO_URI, function (err, db)
if (err) throw new Error(err);
db.collection("users").find(, projection: _id: 0, username: 1, score: 1 )
.sort(score:-1).limit(2)
.toArray(function(err, result)
if (err) throw new Error(err);
console.log(Array.from(result));
res.send( status: true, msg: result );
db.close(); //I think I can omit this line.
);
);
);
在我使函数异步之前,我收到了一个错误报告:
Error: MongoError: Cannot use a session that has ended
我必须使这些脚本异步。
我保留了 mongoose 模式。我仍然能够对用户进行身份验证,并将他们添加到数据库中。
此链接SO Documentation: Node.js Mongodb integration 帮助了我。 SO 是 *** 贡献者制作的文档站点。
【讨论】:
以上是关于设置 Mongoose 模式进行身份验证后,如何使用 Mongodb 查询数据库?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Web API 来对 MVC 应用程序进行身份验证
如何使用 Web API 来对 MVC 应用程序进行身份验证