164

不确定我做错了什么,这是我的 check.js

var db = mongoose.createConnection('localhost', 'event-db');
db.on('error', console.error.bind(console, 'connection error:'));

var a1= db.once('open',function(){
var user = mongoose.model('users',{ 
       name:String,
       email:String,
       password:String,
       phone:Number,
      _enabled:Boolean
     });

user.find({},{},function (err, users) {
    mongoose.connection.close();
    console.log("Username supplied"+username);
    //doSomethingHere })
    });

这是我的 insert.js

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/event-db')

var user = mongoose.model('users',{
     name:String,
     email:String,
     password: String,
     phone:Number,
     _enabled:Boolean
   });

var new_user = new user({
     name:req.body.name,
     email: req.body.email,
     password: req.body.password,
     phone: req.body.phone,
     _enabled:false
   });

new_user.save(function(err){
    if(err) console.log(err); 
   });

每当我尝试运行 check.js 时,都会收到此错误

编译后无法覆盖“用户”模型

我知道这个错误是由于 Schema 不匹配造成的,但我看不到这是在哪里发生的?我对猫鼬和 nodeJS 很陌生。

这是我从 MongoDB 的客户端界面得到的信息:

MongoDB shell version: 2.4.6 connecting to: test 
> use event-db 
  switched to db event-db 
> db.users.find() 
  { "_id" : ObjectId("52457d8718f83293205aaa95"), 
    "name" : "MyName", 
    "email" : "myemail@me.com", 
    "password" : "myPassword", 
    "phone" : 900001123, 
    "_enable" : true 
  } 
>
4

38 回答 38

242

您可能会收到此错误的另一个原因是,如果您在不同的文件中使用相同的模型,但您的require路径有不同的大小写。

例如,在我的情况下,我require('./models/User')在一个文件中,然后在另一个需要访问 User 模型的文件中,我有require('./models/user').

我猜模块和猫鼬的查找将其视为不同的文件。一旦我确定这两个案例都匹配,它就不再是问题了。

于 2015-12-15T13:59:42.480 回答
153

发生错误是因为您已经定义了架构,然后您再次定义架构。通常你应该做的是将模式实例化一次,然后让一个全局对象在需要时调用它。

例如:

user_model.js

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

var userSchema = new Schema({
   name:String,
   email:String,
   password:String,
   phone:Number,
   _enabled:Boolean
});
module.exports = mongoose.model('users', userSchema);          

检查.js

var mongoose = require('mongoose');
var User = require('./user_model.js');

var db = mongoose.createConnection('localhost', 'event-db');
db.on('error', console.error.bind(console, 'connection error:'));
var a1= db.once('open',function(){
  User.find({},{},function (err, users) {
    mongoose.connection.close();
    console.log("Username supplied"+username);
    //doSomethingHere 
  })
});

插入.js

var mongoose = require('mongoose');
var User = require('./user_model.js');

mongoose.connect('mongodb://localhost/event-db');
var new_user = new User({
    name:req.body.name
  , email: req.body.email
  , password: req.body.password
  , phone: req.body.phone
  , _enabled:false 
});
new_user.save(function(err){
  if(err) console.log(err); 
});
于 2013-09-27T13:24:04.807 回答
89

我在“观看”测试时遇到了这个问题。编辑测试时,手表重新运行测试,但由于这个原因它们失败了。

我通过检查模型是否存在然后使用它来修复它,否则创建它。

import mongoose from 'mongoose';
import user from './schemas/user';

export const User = mongoose.models.User || mongoose.model('User', user);
于 2017-05-03T13:18:31.320 回答
66

我在单元测试时遇到了这个问题。

第一次调用模型创建函数时,猫鼬将模型存储在您提供的键下(例如“用户”)。如果您多次使用同一个键调用模型创建函数,猫鼬不会让您覆盖现有模型。

您可以使用以下方法检查模型是否已存在于猫鼬中:

let users = mongoose.model('users')

如果模型不存在,这将引发错误,因此您可以将其包装在 try/catch 中,以便获取模型或创建模型:

let users
try {
  users = mongoose.model('users')
} catch (error) {
  users = mongoose.model('users', <UsersSchema...>)
}
于 2016-07-01T10:26:26.080 回答
42

如果你是离线使用 Serverless 又不想使用--skipCacheInvalidation,可以很好的使用:

module.exports = mongoose.models.Users || mongoose.model('Users', UsersSchema);
于 2018-07-15T18:35:22.907 回答
25

我一直在遇到这个问题,这不是因为架构定义,而是因为无服务器离线模式 - 我只是设法通过以下方式解决它:

serverless offline --skipCacheInvalidation

这里提到了https://github.com/dherault/serverless-offline/issues/258

希望这可以帮助其他在无服务器上构建项目并运行离线模式的人。

于 2017-08-08T16:36:15.757 回答
20

如果你在这里做了,你可能遇到了和我一样的问题。我的问题是我正在定义另一个具有相同名称的模型。我将我的画廊和文件模型称为“文件”。该死的你复制和粘贴!

于 2015-03-06T03:23:41.307 回答
16

我通过添加解决了这个问题

mongoose.models = {}

行前:

mongoose.model(<MODEL_NAME>, <MODEL_SCHEMA>)

希望它能解决你的问题

于 2018-11-27T17:33:49.557 回答
12

当我这样写时,这发生在我身上:

import User from '../myuser/User.js';

但是,真正的路径是 '../myUser/User.js'

于 2017-07-01T06:55:01.437 回答
7

要解决此问题,请检查模型在创建之前是否存在:

if (!mongoose.models[entityDBName]) {
  return mongoose.model(entityDBName, entitySchema);
}
else {
  return mongoose.models[entityDBName];
}
于 2019-06-22T16:44:16.843 回答
5

我知道有一个公认的解决方案,但我觉得当前的解决方案会产生很多样板文件,以便您可以测试模型。我的解决方案本质上是将您的模型放在一个函数中,如果模型尚未注册,则返回新模型,但如果已注册,则返回现有模型。

function getDemo () {
  // Create your Schema
  const DemoSchema = new mongoose.Schema({
    name: String,
    email: String
  }, {
    collection: 'demo'
  })
  // Check to see if the model has been registered with mongoose
  // if it exists return that model
  if (mongoose.models && mongoose.models.Demo) return mongoose.models.Demo
  // if no current model exists register and return new model
  return mongoose.model('Demo', DemoSchema)
}

export const Demo = getDemo()

到处打开和关闭连接是令人沮丧的,并且不能很好地压缩。

这样,如果我要在两个不同的地方或更具体地在我的测试中要求模型,我就不会出错,并且所有正确的信息都会被返回。

于 2017-04-10T13:15:58.063 回答
5

点击这里!官方例子。最重要!事情就是这样导出

export default mongoose.models.Item || mongoose.model('Item', itemsSchema)
于 2021-09-28T05:23:09.590 回答
5

这可能会给一些人带来打击,但我也遇到了错误,并意识到我只是在导入时拼错了用户模型。

错误:const User = require('./UserModel'); 正确:const User = require('./userModel');

难以置信,但考虑一下。

于 2020-09-03T06:01:16.760 回答
3

您还可以做的是在导出时,确保导出现有实例(如果存在)。

打字稿解决方案:

import { Schema, Document, model, models } from 'mongoose';

const UserSchema: Schema = new Schema({
    name: {
        type: String
    }
});

export interface IUser extends Document {
    name: string
}

export default models.Users || model<IUser>('Users', UserSchema);
于 2020-09-03T15:34:11.780 回答
2

这是发生这种情况的另一个原因。也许这可以帮助别人。注意区别,Member s vs Member。他们应该是一样的...

export default mongoose.models.Members || mongoose.model('Member', FamilySchema)

改成:

export default mongoose.models.Member || mongoose.model('Member', FamilySchema)
于 2020-10-09T22:29:55.267 回答
2

我通过这样做解决了这个问题

// Created Schema - Users
// models/Users.js
const mongoose = require("mongoose");

const Schema = mongoose.Schema;

export const userSchema = new Schema({
  // ...
});

然后在其他文件中

// Another file
// index.js
import { userSchema } from "../models/Users";
const conn = mongoose.createConnection(process.env.CONNECTION_STRING, {
    useNewUrlParser: true,
    useUnifiedTopology: true,
});
conn.models = {};
const Users = conn.model("Users", userSchema);
const results = await Users.find({});

更好的解决方案

let User;
try {
  User = mongoose.model("User");
} catch {
  User = mongoose.model("User", userSchema);
}

我希望这有帮助...

于 2020-06-30T05:10:18.560 回答
2
const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const userSchema = new Schema({
    name: String,
});

// Trying to get the existing model to avoid OverwriteModelError
module.exports = mongoose.model("user") || mongoose.model('user', userSchema);
于 2021-10-15T05:44:49.210 回答
2

我在 NextJS 和 MongoDB 地图集上遇到了同样的问题。我有一个模型文件夹,其中存储了会话模型,但问题不在于我两次定义了 Schema。

  1. 确保 Collection 是空的并且没有以前的 Document
  2. 如果是这样,那么只需声明一个没有 Schema 的模型,如下所示:
const Session = mongoose.model("user_session_collection")
  1. 您可以删除以前的记录或备份它们,创建架构,然后在数据库上应用查询。

希望它有所帮助

于 2021-09-01T14:56:25.460 回答
2

还有另一种引发此错误的方法。

请记住,模型的路径区分大小写。

在这个涉及“类别”模型的类似示例中,在以下情况下引发了错误:

1)在两个文件中提到了require语句:..category.js和..index.js 2)我第一个,大小写是正确的,在第二个文件中它不是如下:

类别.js

在此处输入图像描述

index.js

在此处输入图像描述

于 2020-01-21T21:34:15.850 回答
2

如果您使用相同的集合名称定义 2 个不同的架构,则可能会出现此问题

于 2018-01-30T07:00:15.410 回答
1

像这样导出exports.User = mongoose.models.User || mongoose.model('用户', userSchema);

于 2020-12-15T09:12:06.600 回答
1

添加此行将 100% 解决您的错误。

mongoose.models = {}
于 2021-11-28T18:40:12.990 回答
1

有很多好的答案,但为了检查,我们可以做更轻松的工作。我的意思是在最受欢迎的答案中有 check.js ,我们的家伙让它变得如此复杂,我建议:

function connectToDB() {
  if (mongoose.connection.readyState === 1) {
    console.log("already connected");
    return;
  }
  mongoose.connect(
    process.env.MONGODB_URL,
    {
      useCreateIndex: true,
      useFindAndModify: false,
      useNewUrlParser: true,
      useUnifiedTopology: true,
    },
    (err) => {
      if (err) throw err;
      console.log("DB connected");
    },
  );
}

readyState== 1 表示已连接
,因此不会尝试再次连接,
因此您不会收到错误,
我认为这是因为在连接时连接
它是连接到数据库的另一种方式

于 2020-12-25T21:49:23.813 回答
1

以下是在将MongoosePaginationNuxtTypescript结合使用时类似问题的完整解决方案:

import {model, models, Schema, PaginateModel, Document } from 'mongoose';

import { default as mongoosePaginate } from 'mongoose-paginate-v2';

export interface IUser extends Document {
    name: string;
}

const UserSchema: Schema = new Schema({
    name: String
});

UserSchema.plugin(mongoosePaginate)

interface User<T extends Document> extends PaginateModel<T> {}


const User: User<IUser> = models['User'] as User<IUser> || model<IUser>('User', UserSchema) as User<IUser>;

export default User

tsconfig.json

{
    "compilerOptions": {
        "target": "ES2018",
        "module": "ESNext",
        "moduleResolution": "Node",
        "lib": ["ESNext", "ESNext.AsyncIterable", "DOM"],
        "esModuleInterop": true,
        "allowJs": true,
        "sourceMap": true,
        "strict": true,
        "noEmit": true,
        "baseUrl": ".",
        "paths": {
            "~/*": ["./*"],
            "@/*": ["./*"]
        },
        "types": ["@types/node", "@nuxt/types"]
    },
    "exclude": ["node_modules"]
}

要使分页工作,您还需要安装 @types/mongoose-paginate-v2


上述解决方案还应该处理与 Nuxt 热重载(ServerMiddleware错误)和分页插件注册相关的问题。

于 2021-11-01T21:19:54.000 回答
1
If you want to overwrite the existing class for different collection using typescript
then you have to inherit the existing class from different class.

export class User extends Typegoose{
  @prop
  username?:string
  password?:string
}


export class newUser extends User{
    constructor() {
        super();
    }
}

export const UserModel = new User ().getModelForClass(User , { schemaOptions: { collection: "collection1" } });

export const newUserModel = new newUser ().getModelForClass(newUser , { schemaOptions: { collection: "collection2" } });
于 2018-06-24T07:41:02.377 回答
1

我使用 Next.js 和 TypeScript 遇到了这个问题。最重要的答案使得打字不起作用。

这对我有用:

const { Schema } = mongoose

export interface IUser {
  name: string
  email: string
}

const UserSchema = new Schema<IUser>({
  name: { type: String, required: true },
  email: { type: String, required: true },
})

const UserModel = () => mongoose.model<IUser>('User', UserSchema)

export default (mongoose.models.User || UserModel()) as ReturnType<
  typeof UserModel
>
于 2021-08-05T16:17:10.493 回答
1

我有同样的问题,原因是我在 JS 函数中定义了模式模型,它们应该在节点模块中全局定义,而不是在函数中。

于 2019-12-06T18:39:55.810 回答
1

集合的模式定义应该是唯一的,集合的模式不应超过一个。

于 2017-02-22T05:06:53.093 回答
0

我有一种情况,我必须为每个请求动态创建模型,因此我收到了这个错误,但是,我用来修复它的方法是使用deleteModel方法,如下所示:

var contentType = 'Product'

var contentSchema = new mongoose.Schema(schema, virtuals);

var model = mongoose.model(contentType, contentSchema);

mongoose.deleteModel(contentType);

我希望这可以帮助任何人。

于 2018-11-15T23:37:25.333 回答
0

我只是有一个错误的复制粘贴。在一行中,我的名称与其他模型(广告模型)中的名称相同:

const Admin = mongoose.model('Ad', adminSchema);

正确的是:

const Admin = mongoose.model('Admin', adminSchema);

顺便说一句,如果有人有“自动保存”,并使用索引进行如下查询:

**adSchema**.index({title:"text", description:"text", phone:"text", reference:"text"})

它必须删除索引,并为正确的模型重写:

**adminSchema**.index({title:"text", description:"text", phone:"text", reference:"text"})
于 2020-04-12T18:42:25.267 回答
0

您可以通过以下方式轻松解决此问题

delete mongoose.connection.models['users'];
const usersSchema = mongoose.Schema({...});
export default mongoose.model('users', usersSchema);
于 2018-09-29T17:08:57.713 回答
0

确保您没有为两个不同的模式使用相同的模型名称。

例子:

// course model
const mongoose = require("mongoose");
const courseSchema = new mongoose.Schema({
    course: {
        type: String,
        required: true,
    },
    course_category: {
        type: String,
        required: true,
    }
});
module.exports = mongoose.model("course", courseSchema);

// student model
const mongoose = require("mongoose");
const studentSchema = new mongoose.Schema({
    first_name: {
        type: String,
        required: true,
    },
    last_name: {
        type: String,
        required: true,
    }
});
module.exports = mongoose.model("course", studentSchema);
于 2022-02-12T13:33:53.720 回答
0

由于发生此问题是因为再次调用模型。通过将模型代码包装在 try catch 块中来解决此问题。打字稿代码是这样的 -

         Import {Schema, model} from 'mongoose';
         export function user(){
              try{
                   return model('user', new Schema ({
                            FirstName: String,
                            Last name: String
                     }));
              }
             catch{
                   return model('user');
              }
         }

同样,您也可以在 js 中编写代码。

于 2020-05-28T06:04:38.757 回答
0

对于所有因为混合了TypegooseMongoose的代码库而在这里结束的人:

为每个创建一个数据库连接:

猫鼬:

module.exports = db_mongoose.model("Car", CarSchema);

类型鹅:

db_typegoose.model("Car", CarModel.schema, "cars");
于 2019-09-11T13:21:00.313 回答
0

是因为您的架构已经存在,请在创建新架构之前进行验证。

var mongoose = require('mongoose');
module.exports = function () {
var db = require("../libs/db-connection")();
//schema de mongoose
var Schema = require("mongoose").Schema;

var Task = Schema({
    field1: String,
    field2: String,
    field3: Number,
    field4: Boolean,
    field5: Date
})

if(mongoose.models && mongoose.models.tasks) return mongoose.models.tasks;

return mongoose.model('tasks', Task);
于 2018-06-06T07:07:39.563 回答
0
The reason of this issue is: 

you given the model name "users" in the line 
<<<var user = mongoose.model('users' {>>> in check.js file

and again the same model name you are giving in the insert file
<<< var user = mongoose.model('users',{ >>> in insert.js

This "users" name shouldn't be same when you declare a model that should be different 
in a same project.
于 2019-05-31T18:37:07.247 回答
-1

您在 check.js 和 insert.js 中使用具有相同变量名“user”的 mongoose.model。

于 2020-03-08T08:17:39.483 回答
-3

如果您使用的是 expressjs,您可能需要将模型定义移到 app.get() 之外,以便在实例化脚本时只调用一次。

于 2016-01-20T19:16:42.753 回答