web-dev-qa-db-ja.com

Mongooseをコンパイルすると、モデルを上書きできません

私が間違っていることはわかりません、ここに私の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を実行しようとするたびに、このエラーが発生します

コンパイル後に「ユーザー」モデルを上書きできません

このエラーはスキーマの不一致が原因で発生することを理解していますが、これがどこで発生しているかわかりませんか?私は、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" : "[email protected]", 
    "password" : "myPassword", 
    "phone" : 900001123, 
    "_enable" : true 
  } 
>
75
Anathema.Imbued

スキーマが既に定義されているため、エラーが発生し、スキーマを再度定義しています。一般的にすべきことは、スキーマを一度インスタンス化し、必要なときにグローバルオブジェクトから呼び出すようにすることです。

例えば:

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

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

insert.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); 
});
90
thtsigma

このエラーが発生するもう1つの理由は、異なるファイルで同じモデルを使用しているが、requireパスの大文字と小文字が異なる場合です。たとえば、私の状況では次のとおりでした。

require('./models/User')あるファイルに、次に別のファイルにユーザーモデルへのアクセスが必要な場所にrequire('./models/user')がありました。

モジュールとマングースのルックアップは、それを別のファイルとして扱っていると思います。ケースが両方で一致することを確認したら、それは問題ではなくなりました。

141
jonnie

ユニットテスト中にこの問題が発生しました。

モデル作成関数を初めて呼び出すと、mongooseは指定したキー(「ユーザー」など)の下にモデルを保存します。同じキーでモデル作成関数を複数回呼び出すと、mongooseは既存のモデルを上書きできません。

次のコマンドで、モデルがすでにマングースに存在するかどうかを確認できます。

let users = mongoose.model('users')

これは、モデルが存在しない場合にエラーをスローするため、モデルを取得するか作成するために、try/catchでラップできます。

let users
try {
  users = mongoose.model('users')
} catch (error) {
  users = mongoose.model('users', <UsersSchema...>)
}
36
BJ Anderson

テストを「見る」ときにこの問題が発生しました。テストが編集されたとき、時計はテストを再実行しましたが、このまさに理由で失敗しました。

モデルが存在するかどうかを確認して修正し、使用するか、作成します。

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

export const User = mongoose.models.User || mongoose.model('User', user);
30
ZephDavies

私はこの問題を経験しており、それはスキーマ定義のためではなく、サーバーレスオフラインモードのためでした-私はこれでそれを解決することができました:

serverless offline --skipCacheInvalidation

ここで言及されている https://github.com/dherault/serverless-offline/issues/258

サーバーレスでオフラインモードでプロジェクトを構築している他の人の助けになることを願っています。

20
munyah

あなたがここでそれを作った場合、それはあなたが私がやった同じ問題を抱えている可能性があります。私の問題は、iは同じ名前の別のモデルを定義していたでした。ギャラリーとファイルモデルを「ファイル」と呼びました。コピーして貼り付けてください!

13

サーバーレスオフラインを使用していて、--skipCacheInvalidationを使用したくない場合は、次を使用できます。

module.exports = mongoose.models.Users || mongoose.model('Users', UsersSchema);
12
Julian

これは私がこのように書いたときに私に起こりました:

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

ただし、実際のパスは「../myUser/User.js」です

7
ip192

私はこれを追加して解決しました

mongoose.models = {}

行の前:

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

それがあなたの問題を解決することを願っています

5
Toufiq

受け入れられている解決策があることは知っていますが、現在の解決策では、モデルをテストできるように多くの定型文が作成されると感じています。私の解決策は、基本的にモデルを取得し、それを関数内に配置して、モデルが登録されていない場合は新しいモデルを返し、既存のモデルがあればそれを返すことです。

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()

至る所で接続を開いたり閉じたりするのはイライラし、うまく圧縮されません。

このように、モデルに2つの異なる場所、またはより具体的にはテストで必要な場合、エラーは発生せず、すべての正しい情報が返されます。

3
Moosecouture

このチェックを解決するには、作成する前にモデルが存在するかどうかを確認します。

if (!mongoose.models[entityDBName]) {
  return mongoose.model(entityDBName, entitySchema);
}
else {
  return mongoose.models[entityDBName];
}
1
Alpha BA

この問題は、同じコレクション名で2つの異なるスキーマを定義した場合に発生する可能性があります

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
Rohit Jangid

スキーマ定義はコレクションに対して一意である必要があり、コレクションに対して複数のスキーマであってはなりません。

0
KARTHIKEYAN.A

これを簡単に解決できます

delete mongoose.connection.models['users'];
const usersSchema = mongoose.Schema({...});
export default mongoose.model('users', usersSchema);
0
pihyper

スキーマが既にあるため、新しいスキーマを作成する前に検証してください。

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);
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.
0
Rohit Jangid

リクエストごとにモデルを動的に作成する必要がある状況があり、そのためこのエラーを受け取りましたが、それを修正するために使用したのは deleteModel メソッドを次のように使用することです:

var contentType = 'Product'

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

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

mongoose.deleteModel(contentType);

これが誰にも役立つことを願っています。

0
Engr.MTH