簡體   English   中英

設置 ZCCADDEDB567ABAE643E15DCF0974E503Z 模式進行身份驗證后,如何使用 Mongodb 查詢數據庫?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM