为什么我的文档没有在 mongoDB 中更新

问题描述 投票:0回答:1

当尝试使用 Mongoose 的 findOneAndUpdate 方法更新 MongoDB 文档中的嵌套数组字段时,我遇到了一个令人困惑的问题,更新似乎没有反映在数据库中。

以下是问题的简要总结:

我有一个名为 Screen 的 MongoDB 模式,其中包含一个名为 timeslots 的数组字段。在每个时间段内,都有一个称为席位的嵌套数组,代表电影院中的可用座位。我正在尝试更新特定座位的状态字段以表明它已被预订。尽管在本地成功修改了状态字段,但更新不会保留在数据库中。

下面是我的代码片段:

router.post('/bookTicket', async (req, res) => {
    try {
        console.log("Book ticket API is triggered");

        // Find the screen details
        let getDetails = await Screen.findOne({ title: "DemonSlaye" }).lean()
        if (!getDetails) {
            return res.status(404).send("Screen not found");
        }

        console.log("Screen details before update:", getDetails);

        // Find the seat status and update it
        const foundSeat = getDetails.timeslots[0].seats
        .filter(seatTypeIterate => seatTypeIterate.type === 'platinum')
        .map(silverSeatRows => silverSeatRows.rows)
        .flat()
        .find(getrow => getrow.rowname === 'H')
        .cols[0]
        .seats
        .find(getSeatId => getSeatId.seat_id === '2');
        
        if (!foundSeat) {
            console.log("Seat not found");
            return res.status(404).send("Seat not found");
        }

        console.log("Seat status before update:", foundSeat);

        foundSeat.status = "booked";
        foundSeat.bookedBy = "userID";

        console.log("Updated seat status:", foundSeat);

        const hydratedDetails = Screen.hydrate(getDetails);
        console.log("Updating document with ID:", getDetails._id);
        // Replace the entire JSON document in the database with the updated one

        const updatedDocument=await hydratedDetails.save()
        console.log("Document updated successfully:", updatedDocument);

        res.send(updatedDocument)

        // res.send(hydratedDetails); // Sending the updated document as response
    } catch (error) {
        console.error("Error occurred:", error);
        res.status(500).send("An error occurred while booking the ticket.");
    }
});

架构:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;


const screenSchema = new mongoose.Schema({
    status: { type: String},
    seat_id: { type: String},
    bookedBy: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }
});


const rowSchema = new mongoose.Schema({
    rowname: { type: String, required: true },
    cols: [screenSchema] // Array of seats
});


const timeslotSchema = new mongoose.Schema({
    seats: [{
        type: { type: String, required: true },
        rows: [rowSchema], // Array of rows
        price: { type: Number, required: true }
    }]
});



const movieSchema = new mongoose.Schema({
    title: { type: String, required: true },
    theatreId: { type: String, required: true },
    location: { type: String, required: true },
    language: { type: String, required: true },
    time: { type: String, required: true },
    screenType: { type: String, required: true },
    screenName: { type: String, required: true },
    timeslots: [timeslotSchema] // Array of timeslots
},
{ strict: false }
);



const Screen = mongoose.model('Screen', screenSchema);

module.exports = Screen;

输出: 我附上了数据库图像,该图像没有更新座位状态:已预订(seat_id:2)

我尝试使用 $set 运算符,但它不起作用

我的问题在于尝试通过修改使用 findOne 检索的文档,然后使用 Mongoose 的 save 方法将其保存回数据库来更新 MongoDB 文档中的嵌套数组字段。虽然这种方法看起来很直观,但它可能会导致意外的行为,因为 Mongoose 的 save 方法可能不会按预期更新嵌套数组。相反,您应该使用 Mongoose 的 findOneAndUpdate 方法,该方法旨在直接在数据库中更新文档,并且可以更有效地处理嵌套数组。

node.js mongodb mongoose mongoose-schema findoneandupdate
1个回答
0
投票

猫鼬

Model.hydrate()
并不像你想象的那样工作。

当你这样做时:

const hydratedDetails = Screen.hydrate(getDetails);

然后

const updatedDocument = await hydratedDetails.save();

这是同一个文档。与您给它加水时相比,没有任何变化,因此没有保存任何东西。

补水后你需要做出改变。所以类似:

const hydratedDetails = Screen.hydrate(getDetails);
hydratedDetails.title = 'Deamon Slayer 2';
const updatedDocument = await hydratedDetails.save();

所以你最好一开始就不要使用

lean()

但是,我认为它无论如何都不适合你,因为

foundSeat
filter()
map()
返回新数组的结果。它是一个新变量,不再是
getDetails
对象的一部分。当您在
foundSeat
上设置新值时,这些更改不会反映在
getDetails
中。

您的问题源于无法选择正确的

timeslots
。您正在使用数组索引(例如
getDetails.timeslots[0].seats
)从数组中选择一个,因为您没有很好地对数据进行建模。您的
timelsots
应由资源标识符(例如
_id
)选择。然后您就可以执行
findOneAndUpdate
查询。

© www.soinside.com 2019 - 2024. All rights reserved.