猫鼬:将一个元素添加到一个空的子数组中

mongoose: Add an element into an empty child array under

我有以下架构,我在 mongodb 中有一个故事的文档,这个故事没有键“fans”的值,它是一个数组。 我想向这个数组添加一个元素。但是,我试过用fans.push、fans.pop或fans=[element],都不行。请帮助我了解执行此操作的最佳方法。

const personSchema = Schema({
  _id: Schema.Types.ObjectId,
  name: String,
  age: Number,
  stories: [{ type: Schema.Types.ObjectId, ref: 'Story' }]
});

const storySchema = Schema({
  author: { type: Schema.Types.ObjectId, ref: 'Person' },
  title: String,
  fans: [{ type: Schema.Types.ObjectId, ref: 'Person' }]
});

const Story = mongoose.model('Story', storySchema);
const Person = mongoose.model('Person', personSchema);

   const story1 = new Story({
     title: 'Casino Royale',
     author: author._id    // assign the _id from the person
   });

const fan = new Person({
  _id: new mongoose.Types.ObjectId(),
  name:'Fan 001',
  age:38
});
fan.save(function(err){
  if (err) return handleError(err);
  const story1=Story.findOne({title:'Casino Royale'});
  story1.fans=[fan._id];
  story1.save(function (err){
    if (err) return handleError(err);
  });
});

当我运行这个脚本时,我遇到了以下错误:

此处 const story1=Story.findOne({title:'Casino Royale'}); findOne 未返回文档,因此未为此定义保存。 正如documentation中提到的那样returns一个查询 尝试使用 promise 编写代码并等待响应

const story1 = await Story.findOne({title:'Casino Royale'});

因此,要使这一切正常进行,您需要几个步骤:

第 1 步:您需要保存您创建的故事 1,否则 findOne 不会 return 任何东西

第 2 步:您需要等待数据库调用,因为它们是异步的

我会提供一个利用数据库更新方法的代码,直接push到数据库中会更干净更快。

所以这里是你的代码更正:

const personSchema = Schema({
            _id: Schema.Types.ObjectId,
            name: String,
            age: Number,
            stories: [{ type: Schema.Types.ObjectId, ref: 'Story' }]
        });

        const storySchema = Schema({
            author: { type: Schema.Types.ObjectId, ref: 'Person' },
            title: String,
            fans: [{ type: Schema.Types.ObjectId, ref: 'Person' }]
        });

        const Story = mongoose.model('Story', storySchema);
        const Person = mongoose.model('Person', personSchema);

        const author = { name: 'asdsd', _id: "aaaaaaaaaaaaaaaaaaaaaaaa" } // Note I hardcoded an id here

        const story1 = new Story({
            title: 'Casino Royale',
            author: author._id // Assign the _id from the person
        });
        await story1.save() // Await

        const fan = new Person({
            _id: new mongoose.Types.ObjectId(),
            name: 'Fan 001',
            age: 38
        });
        await fan.save(async function(err) { // Await since we have to await the database
            if (err) return handleError(err);
            const story1 = await Story.findOne({ title: 'Casino Royale' }); // Await database
            console.log(story1)
            story1.fans.push(fan._id);
            await story1.save(function(err) { // Await again
                if (err) return handleError(err);
            });
        });

这是更好版本的代码(请注意,架构不再有 _id,因为它是由 mongoDb 提供的):

const personSchema = Schema({
            name: String,
            age: Number,
            stories: [{ type: Schema.Types.ObjectId, ref: 'Story' }]
        });

        const storySchema = Schema({
            author: { type: Schema.Types.ObjectId, ref: 'Person' },
            title: String,
            fans: [{ type: Schema.Types.ObjectId, ref: 'Person' }]
        });

        const Story = mongoose.model('Story', storySchema);
        const Person = mongoose.model('Person', personSchema);

        const author = { name: 'asdsd', _id: "aaaaaaaaaaaaaaaaaaaaaaaa" } // Note I hardcoded an id here

        // Create a Story that is immediately saved in the database and gets an _id by mongoDb
        await Story.create({
            title: 'Casino Royale',
            author: author._id
        })

        // Create a Person that is immediately saved in the database and gets an _id by mongoDb
        const fan = await Person.create({
            name: 'Fan 001',
            age: 38
        })

        // Add the Person to the stories fans array
        const story1 = await Story.findOneAndUpdate(
            { title: 'Casino Royale' }, 
            { $push: { 'fans': fan._id } }, 
            { new: true })

        console.log(story1)