无法编译模型,因为已经被编译过了 Mongoose

205

我不确定我做错了什么,这是我的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时,都会出现以下错误:

无法在编译后覆盖“users”模型

我知道这个错误是由Schema不匹配造成的,但我看不出具体哪里出了问题?我对mongoose和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 
  } 
>

这是我从MongoDB客户端接口获取的信息: MongoDB shell版本:2.4.6 连接到:测试
use event-db 切换到数据库event-db db.users.find() { "_id" : ObjectId("52457d8718f83293205aaa95"), "name" : "MyName", "email" : "myemail@me.com", "password" : "myPassword", "phone" : 900001123, "_enable" : true }
- Anathema.Imbued
有时候我们犯的错误很愚蠢,就像我的情况一样:导出文件的代码是这样的{userModel:model("user",userSchema)...所以每次访问该文件时都会重新创建模型并触发错误...因此,不要像这样导出,而是创建一个常量"const userModel=model("user",userSchema),然后像这样导出module.exports = { userModel }。 - Bakaji
50个回答

2

有另一种方法可以抛出此错误。

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

在这个涉及“Category”模型的类似示例中,在以下情况下会抛出错误:

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

category.js

enter image description here

index.js

enter image description here


2
您可以通过执行以下操作轻松解决此问题:
delete mongoose.connection.models['users'];
const usersSchema = mongoose.Schema({...});
export default mongoose.model('users', usersSchema);

适用于动态模式情况的有用工具 - May'Habit

2
我找到的解决方案是,在创建并导出模型之前,先检查模型实例是否存在。
import mongoose from "mongoose";
const { Schema } = mongoose;
const mongoosePaginate = require("mongoose-paginate");

const articleSchema = new Schema({
  title: String, // String is shorthand for {type: String}
  summary: String,
  data: String,
  comments: [{ body: String, date: Date }],
  date: { type: Date, default: Date.now },
  published: { type: Boolean, default: true },
  tags: [{ name: String }],
  category: String,
  _id: String,
});


const Post = mongoose.models.Post ? mongoose.models.Post : mongoose.model("Post",articleSchema);

export default Post;


这个解决方案可以工作,但也会出现另一个错误。这个更改使得像.create().findById等表达式不可调用。我已经提供了修复方法! - Haneen Mahdin

2

如果您遇到了覆盖问题,您应该检查模型。

let User

if (mongoose.models.User) {
    User = mongoose.model('User')
} else {
    User = mongoose.model('User', userSchema)
}

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);
}

我希望这能帮到您...


1
不知道为什么提供解释如此困难。想象一下,每个人都要阅读你的代码所浪费的时间。 - danefondo

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" } });

1

请确保您不会在两个不同的模式中使用相同的模型名称。

示例:

// 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);

1
我曾经遇到同样的问题,原因是我在JS函数中定义了架构和模型,它们应该在一个节点模块中全局定义,而不是在函数中定义。

1
集合的模式定义应该是唯一的,一个集合不应该有多个模式。

1

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接