我有一個包含 2 個模型的應用程式:學生、書籍(見下文)。每當添加一本書時,我希望它被附加到每個學生模型的書籍陣列中。根據我的理解,Mongoose 的 updateMany 函式應該這樣做,盡管它從不更新陣列。
POST 函式根據給定的 ISBN 創建一個新的書籍物件,并將其附加到學生模型的每個書籍陣列中:
if (req.isAuthenticated()) {
if (req.body.ISBN && req.body.dueDate) {
https.get('https://www.googleapis.com/books/v1/volumes?q=isbn:' req.body.ISBN, function (hres) {
var body = "";
hres.on('data', function (chunk) {
body = chunk;
});
hres.on('end', function () {
var resp = JSON.parse(body);
const newBook = new book({
title: resp.items[0].volumeInfo.title,
length: resp.items[0].volumeInfo.pageCount,
author: resp.items[0].authors,
ISBN: req.body.ISBN,
finished: false,
dueDate: req.body.dueDate
});
newBook.save();
student.updateMany({},{$push: {books:newBook}})
});
});
res.redirect('/admin')
}
else {
res.redirect('/newBook');
}
}
else {
res.redirect('/Login')
}
學生模型:
const mongoose = require('mongoose');
const bookSchema = require('./book').schema;
const studentSchema = new mongoose.Schema({
name:{
type: String,
required: true
},
books:{
type: [bookSchema]
}
});
module.exports = mongoose.model("student", studentSchema);
圖書型號:
const mongoose = require('mongoose');
const bookSchema = new mongoose.Schema({
title:{
type: String
},
length:{
type:Number
},
author:{
type:String
},
ISBN:{
type:String
},
finished:{
type:Boolean
},
dueDate:{
type:String
}
});
module.exports = mongoose.model("book", bookSchema);
uj5u.com熱心網友回復:
student.updateMany({},{$push: {books:newBook}})是正確的語法,但await如果您使用 Promise,則需要該詞才能正常作業。
如果要使用回呼,則需要添加.exec()在操作結束時添加,這樣你就告訴 mongoose 運行該命令。
student.updateMany({},{$push: {books:newBook}}).exec((err,studentsUpdated)=>{
// respond here
})
使用異步等待(我推薦)
try {
const newBook = new book({
title: resp.items[0].volumeInfo.title,
length: resp.items[0].volumeInfo.pageCount,
author: resp.items[0].authors,
ISBN: req.body.ISBN,
finished: false,
dueDate: req.body.dueDate
});
const newBookAdded = await newBook.save();
const studentsUpdated = await student.updateMany({},{$push: {books:newBookAdded}})
// Anwer here, if you console.log(studentsUpdated) you can check if the updateMany operation was correct
} catch (error) {
// manage the error here
}
提醒您需要運行以在更高功能上添加異步字才能使用等待,您的代碼應該在這里
async function (hres)
uj5u.com熱心網友回復:
正如 Fernando 所提到的,您現有的解決方案需要await關鍵字才能正確執行。要使用await,您必須將現有功能轉換為async功能。最重要的是,還鼓勵使用async-await而不是回呼鏈以提高可讀性。
評論
另請注意,一旦您呼叫new book()mongoose 將創建新的 unique _id。這意味著,如果您使用相同的 ISBN 多次呼叫此函式,您的books集合和集合books陣列students最終將包含具有相同 ISBN 但不同的相同書籍_id。因此,一種可能的策略是有兩個功能,一個處理新書的創建,另一個處理書的更新,例如更新dueDate現有的書。然后,我們可能想在addNewBook添加新書之前檢查函式中的現有書。因此,添加新書的函式可以寫成如下
// another import up here...
// we will use axios to replace https
const axios = require("axios");
exports.addNewBook = async (req, res, next) => {
try {
if (!req.isAuthenticated()) {
res.redirect("/newBook");
return;
}
const ISBN = req.body.ISBN;
const dueDate = req.body.dueDate;
if (!ISBN || !dueDate) {
res.redirect("/Login");
return;
}
const existingBook = await book.find({ ISBN }).exec();
// book exists. skipping save() and updateMany()
if (existingBook.length !== 0) {
res.status(400).json({
message: `Failed to add new book. Book with ISBN ${ISBN} exists in database`,
});
return;
}
const bookRes = await axios.get(
"https://www.googleapis.com/books/v1/volumes?q=isbn:" ISBN
);
const bookData = bookRes.data;
const newBook = new book({
title: bookData.items[0].volumeInfo.title,
length: bookData.items[0].volumeInfo.pageCount,
author: bookData.items[0].authors,
ISBN: ISBN,
finished: false,
dueDate: dueDate,
});
const savedBook = await newBook.save();
const updateResult = await student.updateMany({}, { $push: { books: savedBook } });
res.redirect("/admin");
} catch (err) {
// handle error
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/503949.html
上一篇:命令列Nodemon
