javascript Mongoose updateOne覆盖嵌套的文档数组,而不是向数组中添加文档

8mmmxcuj  于 2023-05-05  发布在  Java
关注(0)|答案(1)|浏览(224)

我正在尝试将一个新的嵌套Item文档添加到List文档中的文档数组中。它不会将Item文档添加到数组中,而是覆盖现有文档并用新文档替换它们。
代码如下:

app.post('/', async (req, res) => {
        const item = req.body.item;

        const newItem = new Item({
            name: item,
        });

        // Takes the value from the submit button
        const list = req.body.list.toLocaleLowerCase();

        await List.updateOne({ name: list }, { items: newItem });

        res.redirect('/');
    });

下面是与List交互的其余代码:

const itemsSchema = new Schema({
        name: { type: String, required: [true, `The field name is required.`] },
    });

const listsSchema = new Schema({
        name: {
            type: String,
            required: [true, `The name of the list is required.`],
        },
        items: [itemsSchema],
    });

    const List = mongoose.model('List', listsSchema);

app.get('/:list', async (req, res) => {
        // Get the requested title by the user and lower case it.
        const titleRequested = req.params.list.toLocaleLowerCase();

        // Upper case the first letter.
        const upperCasedTitle =
            titleRequested.at(0).toLocaleUpperCase() + titleRequested.slice(1);

        // Find if the list with the requested title exists in the database.
        await List.findOne({ name: titleRequested }).then(async list => {
            if (!list) {
                const newList = new List({
                    name: titleRequested,
                    items: new Item({
                        name: `You've created a ${titleRequested} list!`,
                    }),
                });

                await newList.save();

                await List.findOne({ name: titleRequested }).then(document => {
                    res.render('list', {
                        // De aca sale el value="<%= title %>"
                        title: upperCasedTitle,
                        items: document.items,
                    });
                    console.log(`${upperCasedTitle} list created succesfully.`);
                });
            } else if (list) {
                await List.findOne({ name: titleRequested }).then(document => {
                    res.render('list', {
                        // value="<%= title %>"
                        title: upperCasedTitle,
                        items: document.items,
                    });
                });
            }
        });
    });

是否有任何方法可以更新查询找到的List文档,而不覆盖现有的嵌套文档?
如果有一个特定的Model.prototype函数可以做到这一点,我还没有找到它:(

jk9hmnmh

jk9hmnmh1#

按照Adding Subdocs to Arrays文档,我们可以在子文档字段上使用.push(subDoc).create(subSoc)方法将子文档添加到数组中。
例如:
model/list.ts

import mongoose, { Schema } from 'mongoose';
import { itemSchema } from './item';

export const listsSchema = new Schema({
  name: {
    type: String,
    required: [true, `The name of the list is required.`],
  },
  items: [itemSchema],
});

export const List = mongoose.model('list', listsSchema);

models/item.ts

import { Schema } from 'mongoose';

export const itemSchema = new Schema({
  name: { type: String, required: [true, `The field name is required.`] },
});

main.ts

import { List } from './models/list';
import mongoose from 'mongoose';
import { config } from '../../src/config';

async function main() {
  mongoose.connect(config.MONGODB_URI, { useNewUrlParser: true, useUnifiedTopology: true });
  const db = mongoose.connection;
  db.on('error', console.error.bind(console, 'connection error:'));
  db.once('open', async () => {
    // seed
    const list = new List({ name: 'list-a', items: [{ name: 'item-a' }, { name: 'item-b' }] });
    await list.save();

    // query and add subdoc 
    const listDoc = await List.findOne({ name: 'list-a' });
    listDoc.items.push({ name: 'item-c' });
    await listDoc.save();
    
    // query and check
    console.log('list-a: ', await List.findOne({ name: 'list-a' }));

    await db.dropCollection('lists');
    db.close();
  })
}

main();

执行结果:

list-a:  {
  _id: 645387bae5d6004f6d3607f7,
  name: 'list-a',
  items: [
    { _id: 645387bae5d6004f6d3607f8, name: 'item-a' },
    { _id: 645387bae5d6004f6d3607f9, name: 'item-b' },
    { _id: 645387bae5d6004f6d3607fa, name: 'item-c' }
  ],
  __v: 1
}

如您所见,我们成功地将名称为item-c的项添加到list.items数组中。

相关问题