【问题标题】:MongoDB - Error: document must have an _id before savingMongoDB - 错误:文档在保存之前必须有一个 _id
【发布时间】:2022-05-05 18:48:45
【问题描述】:

我一直在为这个项目苦苦挣扎。我正在关注一个在某些领域已经过时的教程,例如他们的 Jquery 版本对某些功能使用了完全不同的格式,我不得不做很多改变。但我想我要解决最后一个我似乎无法解决的主要问题。在我的 Schema 变量中,我有 _id、用户名和密码类型

var UserSchema = new mongoose.Schema({
    _id: mongoose.Schema.ObjectId,
    username: String,
    password: String
}); 

但是当我尝试向我的应用程序添加一个新用户时,它没有得到我应该得到的警报,而是作为 [object Object] 弹出,并且没有任何内容添加到数据库中。然后在mongo cmd中弹出这个错误

“错误:文档在保存之前必须有一个_id”。

我尝试注释掉 _id 行,我得到了正确的消息,但我的数据库中仍然没有显示任何内容。

【问题讨论】:

    标签: node.js mongodb


    【解决方案1】:

    很简单:

    1. 如果您已在架构中显式声明 _id 字段,则必须显式初始化它
    2. 如果没有在 schema 中声明,MongoDB 会声明并初始化它。

    你不能做的是将它放在架构中但不初始化它。它会抛出你所说的错误

    【讨论】:

    • 我担心如果 Id 未声明,那么在查找文档时将没有 id。但是 id 被返回了,所以最好不要在模式中声明 id .. 这样更干净更容易
    【解决方案2】:

    您可以在没有 _id 的情况下编写模型,以便自动生成

    您可以使用 .init() 来初始化数据库中的文档。

    喜欢:

    const mongoose = require('mongoose');
    
    const UserSchema = mongoose.Schema({
      _id: mongoose.Schema.Types.ObjectId,
      username: String,
      password: String
    })
    
    module.exports = mongoose.model('User', UserSchema);
    

    然后

    const User = require('../models/user');
    
    router.post('/addUser',function(req,res,next){
    
      User.init() // <- document gets generated
    
      const user = new User({
        username: req.body.username,
        password: req.body.password
      })
    
      user.save().then((data)=>{
        console.log('save data: ',data)
       // what you want to do after saving like res.render
      })
    }
    

    【讨论】:

      【解决方案3】:

      试试下面的 sn-p 我想将 _id 命名为 userId 你也可以不用它。

      var Schema = mongoose.Schema,
      ObjectId = Schema.ObjectId;
      
      var UserSchema = new Schema({
          username: String,
          password: String
      });
      UserSchema.virtual('userId').get(function(){
          return this._id;
      });

      【讨论】:

        【解决方案4】:

        如果您将猫鼬与nest jsGraphQL 一起使用,我已通过将id 更改为_id 并删除它上面的@prop 来修复它,即使id 问题的空值也有消失了。 example on github

        import { ObjectType, Field, Int, ID } from '@nestjs/graphql';
        import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
        import { Document } from 'mongoose';
        import { User } from 'src/user/entities/user.entity';
        import * as mongoose from 'mongoose';
        
        export type SchoolDocument = School & Document;
        @ObjectType()
        @Schema()
        export class School {
          @Prop()//remove this
          @Field(() => ID,{ nullable: true })
          _id: string;
          @Prop()
          @Field(() => String,{ nullable: true })
          name: string;
          @Field(()=>[User],{nullable:true})
          users:User[];
        }
        export const SchoolSchema= SchemaFactory.createForClass(School);
        

        【讨论】:

          【解决方案5】:

          _id 由 MongoDb 自动添加。

          如果您想在数据结构中保留 _id,请务必正确初始化:

          import { Types } from "mongoose";
          
          const obj = new UserSchema({ 
            "_id": new Types.ObjectId(), 
            "username": "Bill", 
            "password" : "...." 
          });
          

          【讨论】:

            【解决方案6】:

            在我的例子中,我不小心在我的架构末尾出现了以下内容。删除有效:

            { _id: false }
            

            【讨论】:

              【解决方案7】:

              看看我修复的方式是我只在 json post request 中输入了 id 而不是 _id。

              【讨论】:

                【解决方案8】:

                NestJS 与猫鼬 (@nestjs/mongoose) 解决方案

                我修复了错误

                1. 删除上面的@Prop() _id
                2. mongoose.Types.ObjectId 作为类型添加到_id
                import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
                import mongoose from 'mongoose';
                import { Document } from 'mongoose';
                
                export type CompanyDocument = Company & Document;
                
                @Schema()
                export class Company {
                  _id: mongoose.Types.ObjectId;
                
                  @Prop({ unique: true })
                  name: string;
                }
                
                export const CompanySchema = SchemaFactory.createForClass(Company);
                
                

                【讨论】:

                  【解决方案9】:

                  无需在模型中指定文档_id。如果您像这样省略_id,系统会自动生成id:

                  var UserSchema = new mongoose.Schema({    
                      username: String,
                      password: String
                  }); 
                  

                  话虽如此,如果您仍想自己生成 _id,请参阅上面的答案。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2020-02-22
                    • 2018-09-26
                    相关资源
                    最近更新 更多