[英]How do I query the database using Mongodb after I set up a Mongoose schema for authentication?
我成功地為我的應用程序設置了身份驗證,這是一個 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 應用程序中的注冊和登錄 forms 添加用戶之前,此集合不存在。
現在我想在數據庫中使用相同的集合(“用戶”)來測試 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 文件中。 我也沒有 Mongoose 架構。 我只有 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 model 之前,上述方法運行良好,我現在也無法顯示排行榜結果。 在終端中輸入“節點應用程序”后,我在控制台上收到“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 模式進行身份驗證。 這個模式會自動創建注冊用戶的集合。 (我沒有任何真實用戶;我使用虛假用戶配置文件來測試該過程。)我還假設 mongoose 和 mongodb 之間存在差異。
如果我可以使用舊方法,那將是最好的,因為我可以在腳本中使用 async/await。 但是,主要問題是我根本沒有得到任何結果,只有錯誤消息,盡管在添加身份驗證之前我能夠執行許多涉及數據庫的操作。
我可以通過編寫到 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.
});
});
});
在我使 function 異步之前,我收到了一個錯誤報告:
Error: MongoError: Cannot use a session that has ended
我必須使這些腳本異步。
我按原樣保留了 mongoose 架構。 我仍然能夠對用戶進行身份驗證,並將他們添加到數據庫中。
此鏈接SO 文檔:Node.js Mongodb 集成幫助了我。 SO 是由 StackOverflow 貢獻者制作的文檔站點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.