एक बार Mongoose संकलित मॉडल को अधिलेखित नहीं कर सकता


109

नहीं यकीन है कि मैं क्या गलत कर रहा हूँ, यहाँ मेरे 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 })
    });

और यहाँ मेरा इन्सर्ट है। 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 चलाने का प्रयास कर रहा हूं, मुझे यह त्रुटि मिल रही है

एक बार संकलित किए जाने के बाद 'उपयोगकर्ताओं के मॉडल को अधिलेखित नहीं किया जा सकता

मैं समझता हूं कि यह त्रुटि स्कीमा के बेमेल होने के कारण आती है, लेकिन मैं यह नहीं देख सकता कि यह कहां हो रहा है? मैं आम और नोड्स के लिए बहुत नया हूं।

यहाँ मैं अपने 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 शेल संस्करण: 2.4.6 कनेक्टिंग: टेस्ट> ईवेंट-डीबी को db ईवेंट-डीबी> db.users.find () {"_ _id" पर स्विच करना: ObjectId ( "52457d8718f83293205aaa95"), "नाम": "MyName", "ईमेल": "myemail@me.com" "पासवर्ड": "myPassword", "फोन": 900,001,123, "_enable": सच}>
अभिशाप .Imbued

जवाबों:


110

त्रुटि इसलिए हो रही है क्योंकि आपके पास पहले से ही एक स्कीमा परिभाषित है, और फिर आप स्कीमा को फिर से परिभाषित कर रहे हैं। आम तौर पर आपको जो करना चाहिए, वह स्कीमा को एक बार इंस्टेंट कर देता है, और उसके बाद एक वैश्विक ऑब्जेक्ट को इसकी आवश्यकता होने पर कॉल करता है।

उदाहरण के लिए:

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

69
निर्यात / आवश्यकता वाले मॉडल से बचें - यदि किसी refअन्य मॉडल के लिए है तो यह निर्भरता दुःस्वप्न का कारण बन सकता है। के var User = mongoose.model('user')बजाय का उपयोग करें require
14

1
स्कीमा माइग्रेशन कोड के परीक्षण के लिए परिभाषित करने के बाद स्कीमा को बदलना वास्तव में उपयोगी हो सकता है।
इगोर सोरेज़

1
@ क्या आप इसे आगे समझा सकते हैं? क्यों यह समस्या पैदा करने की आवश्यकता होगी?
वरुण

यह उत्तर भ्रामक है। तथ्य यह है कि अगर केवल एक mongoDB सर्वर आवृत्ति और अधिक डेटाबेस है, यदि आप किसी अन्य ऐप में पहले से ही लिया गया डेटाबेस को परिभाषित करते हैं तो आपको ऐसी त्रुटि मिली। बस के रूप में
कारमाइन Tambascia

174

तो एक और कारण है कि आपको यह त्रुटि मिल सकती है यदि आप एक ही मॉडल को विभिन्न फ़ाइलों में उपयोग करते हैं लेकिन आपके require रास्ते में एक अलग मामला है। मेरी स्थिति में उदाहरण के लिए मेरे पास था:

require('./models/User') एक फ़ाइल में और फिर दूसरी फ़ाइल में जहाँ मुझे उस उपयोगकर्ता मॉडल तक पहुँच की आवश्यकता थी जो मेरे पास था require('./models/user')

मुझे लगता है कि मॉड्यूल और मानस के लिए लुक अप इसे एक अलग फाइल के रूप में मान रहा है। एक बार जब मैंने यह सुनिश्चित कर लिया कि मामला दोनों में मेल खाता है तो यह कोई मुद्दा नहीं था।


7
यह वास्तव में बहुत मुश्किल समस्या है - मुझे लगता है कि यह ओएस विशिष्ट है (यह केवल मैक और विंडोज पर होना चाहिए क्योंकि एफएस मामले की अनदेखी करता है)। मुझे यह समस्या थी, लेकिन सौभाग्य से आपका जवाब देखा :) बहुत बहुत धन्यवाद जॉनी!
मिरोस्लाव निदालकोव

6
यह समस्या मेरे OS X सिस्टम में होती है।
lutaoact

मैं इसके बारे में कभी नहीं सोच सकता था, कम से कम सहज रूप से नहीं! धन्यवाद
नवीन अत्री

यह पूरी तरह से मेरा मुद्दा था। हालांकि मुझे कभी भी ऊपरी आवरण नाम की कोई समस्या नहीं हुई।
संदीप सूबेदार

मेरे लिए भी यही था। सभी ओला OS X और उसके (डिफ़ॉल्ट रूप से असंवेदनशील) फ़ाइल सिस्टम
mithril_knight

50

यूनिट परीक्षण के दौरान मेरे पास यह मुद्दा था।

पहली बार जब आप मॉडल निर्माण फ़ंक्शन को कॉल करते हैं, तो आपके द्वारा प्रदान की जाने वाली कुंजी (जैसे 'उपयोगकर्ता') के तहत मॉडल को मॉंगोज़ स्टोर करता है। यदि आप मॉडल निर्माण फ़ंक्शन को एक से अधिक बार एक ही कुंजी के साथ कहते हैं, तो मानसून आपको मौजूदा मॉडल को अधिलेखित नहीं करने देगा।

आप देख सकते हैं कि क्या मॉडल पहले से ही साथ में मौजूद है:

let users = mongoose.model('users')

यदि मॉडल मौजूद नहीं है, तो यह एक त्रुटि फेंक देगा, इसलिए आप इसे मॉडल को प्राप्त करने के लिए एक कोशिश / पकड़ में लपेट सकते हैं या इसे बना सकते हैं:

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

1
+1 मेरे पास वही मुद्दा था जहां मुझे अपने स्कीमा को परिभाषित करने से पहले एक प्लगइन के लिए कुछ कॉन्फ़िगरेशन सेटअप करने की आवश्यकता थी। यह मोचा के साथ बिल्कुल भी अच्छा नहीं खेला और अंत में मैंने हार
विक्टर परमार

मैं उसी का उपयोग कर रहा हूं, लेकिन दूसरे तरीके से, यह दुष्ट है:try exports.getModel = ()-> mongoose.model('User', userSchema) catch err exports.getModel = ()-> mongoose.model('User')
एंडी गीगा

शुक्रिया सर, इस समस्या पर 5+ घंटे बर्बाद। मैं नोड सर्वर के विपरीत सर्वर रहित के साथ काम कर रहा था जिसका मैं उपयोग कर रहा हूं।
mxdi9i7

43

परीक्षण देखने के दौरान मेरे पास यह मुद्दा था। जब परीक्षणों को संपादित किया गया, तो घड़ी ने परीक्षणों को फिर से चलाया, लेकिन वे इस कारण से असफल रहे।

मैंने यह जाँच कर तय किया कि यदि मॉडल मौजूद है तो उसका उपयोग करें, अन्यथा इसे बनाएं।

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

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

इसने मेरे लिए काम किया। मैं बदल गया module.export = Userथा export defaults User। मुझे refsअन्य मॉडलों से उपयोगकर्ता भी लेना था । मैं अनिश्चित हूं कि इस मुद्दे module.exportsको क्यों export defaultलाया गया। फिर भी, इस जवाब ने इसे तय कर दिया है।
रन

3
खराब करने के लिए mongoose.modelsमौजूद नहीं है, कम से कम हाल के संस्करणों में
पेड्रो लूज

1
मेरे पास एक ही मुद्दा था, लेकिन सभी परीक्षणों से पहले सभी मॉडलों को साफ करने के साथ इसे तय किया:for (let model in mongoose.models) delete mongoose.models[model]
ई। सुंदर

मेरे परीक्षण स्क्रिप्ट दिखता है तो चाहते: "test": "NODE_ENV=test mocha --file mocha.config.js --watch"और उस config js फ़ाइल में मैं एक है before()और after()संभाल सेटअप और टियरडाउन करने के लिए। @ E.Sundin ने यहां सही समाधान दिया, और यह एक आकर्षण की तरह काम करता है। धन्यवाद!
ब्रेंडन आस्कोव

21

मैं इस मुद्दे का अनुभव कर रहा हूं और यह स्कीमा परिभाषाओं के कारण नहीं था, बल्कि सर्वर रहित ऑफ़लाइन मोड के कारण था - मैं बस इसे हल करने में कामयाब रहा:

serverless offline --skipCacheInvalidation

जिसका उल्लेख यहाँ किया गया है https://github.com/dherault/serverless-offline/issues/258 है

उम्मीद है कि किसी और की मदद करता है जो सर्वर रहित और ऑफ़लाइन मोड पर अपनी परियोजना का निर्माण कर रहा है।


2
बहुत मददगार। धन्यवाद।
थान ट्रूंग

2
मैंने यह पाया कि कैश अमान्य होना, लगातार पुनः लोड करना छोड़ना कष्टप्रद है, इसके बजाय यह काम करता हैmodule.exports = mongoose.models.Users || mongoose.model('Users', UsersSchema);
Ask_io

आपने मेरा दिन बनाया
फस्टसी

बहुत - बहुत धन्यवाद!
एंडीज़ान

यह बहुत मददगार था। धन्यवाद!
ifiok

20

यदि आप सर्वर रहित ऑफ़लाइन का उपयोग कर रहे हैं और उपयोग नहीं करना चाहते हैं --skipCacheInvalidation, तो आप बहुत अच्छी तरह से उपयोग कर सकते हैं:

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

यदि आप एक मॉडल को दूसरे के अंदर आयात कर रहे हैं, तो भी आपको इसका इस्तेमाल करना होगा, यहां तक ​​कि--skipCacheInvalidation
पाउडरहम

1
यह सटीक उत्तर है जिसकी मुझे तलाश थी, Next.js. में उपयोग के लिए काश यह पृष्ठ पर अधिक होता!
ब्रेंडन नी

18

यदि आपने इसे यहां बनाया है तो संभव है कि आपको वही समस्या थी जो मैंने की थी। मेरा मुद्दा यह था कि मैं इसी नाम के साथ एक और मॉडल को परिभाषित कर रहा था । मैंने अपनी गैलरी और मेरे फ़ाइल मॉडल को "फ़ाइल" कहा। हिम्मत तुम कॉपी और पेस्ट करो!


11

मेरे साथ ऐसा हुआ जब मैं इस तरह लिखता हूं:

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

हालाँकि, सही रास्ता '../myUser/User.js' है


आयात करते समय स्कीमा पथों के मामले को मिलाने से यह समस्या उत्पन्न होती है - यह जाँच लें कि स्कीमा आयात करने वाली सभी फाइलें एक ही मामले का उपयोग करती हैं।
एंड्रयू क्यूपर

इसने हमें बचाया! हम एक महसूस कर रही है इस वजह से विंडोज़ का उपयोग करने के लिए हो सकता है
Lyka

11

मैंने इसे जोड़कर हल किया

mongoose.models = {}

लाइन से पहले:

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

आशा है कि यह आपकी समस्या को हल कर देगा


मैंने यही किया और इसे ठीक किया। mongoose.connection.models = {};
फॉर्च्यून

6

इस जाँच को हल करने के लिए कि क्या मॉडल निर्माण करने से पहले मौजूद है:

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

4

मुझे पता है कि एक स्वीकृत समाधान है, लेकिन मुझे लगता है कि वर्तमान समाधान के परिणामस्वरूप बहुत सारे बॉयलरप्लेट हैं ताकि आप मॉडल का परीक्षण कर सकें। मेरा समाधान अनिवार्य रूप से आपको मॉडल लेना है और इसे एक फ़ंक्शन के अंदर रखना है जिसके परिणामस्वरूप नया मॉडल वापस आ गया है यदि मॉडल पंजीकृत नहीं किया गया है लेकिन मौजूदा मॉडल वापस आ रहा है यदि यह है।

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

सभी स्थानों पर कनेक्शन खोलना और बंद करना निराशाजनक है और अच्छी तरह से संपीड़ित नहीं करता है।

इस तरह अगर मुझे मॉडल की दो अलग-अलग जगहों या विशेष रूप से अपने परीक्षणों में आवश्यकता होती है, तो मुझे त्रुटियां नहीं मिलेंगी और सभी सही जानकारी वापस मिल जाएगी।



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

मेरे पास एक ही समस्या थी, इसका कारण मुझे जेएस फ़ंक्शन में स्कीमा को एक मॉडल के रूप में परिभाषित किया गया था, उन्हें एक नोड मॉड्यूल में वैश्विक रूप से परिभाषित किया जाना चाहिए, एक फ़ंक्शन में नहीं।


1

इस त्रुटि को फेंकने का एक और तरीका है।

ध्यान रखें कि मॉडल का मार्ग संवेदनशील है।

"श्रेणी" मॉडल को शामिल करने वाले इस तरह के उदाहरण में, इन शर्तों के तहत त्रुटि डाली गई थी:

1) आवश्यकता विवरण में दो फाइलों का उल्लेख किया गया था: .. श्रेणीबद्ध .js और ..index.js 2) मैं पहला था, मामला सही था, दूसरी फाइल में यह निम्नानुसार नहीं था:

category.js

यहां छवि विवरण दर्ज करें

index.js

यहां छवि विवरण दर्ज करें


0

स्कीमा की परिभाषा एक संग्रह के लिए अद्वितीय होनी चाहिए, यह संग्रह के लिए एक स्कीमा से अधिक नहीं होनी चाहिए।


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

0

आप इसे आसानी से कर सकते हैं

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

0

मेरे पास एक ऐसी स्थिति है जहां मुझे प्रत्येक अनुरोध के साथ मॉडल को गतिशील रूप से बनाना है और इस वजह से मुझे यह त्रुटि मिली है, हालांकि, जो मैंने इसे ठीक करने के लिए उपयोग किया था , वह निम्न की तरह deleteModel विधि का उपयोग कर रहा है :

var contentType = 'Product'

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

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

mongoose.deleteModel(contentType);

मुझे उम्मीद है कि इससे कोई मदद मिल सकती है।


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.

0

सभी लोगों को यहां के एक मिश्रण के साथ एक codebase की वजह से समाप्त Typegoose और नेवला :

हर एक के लिए एक db कनेक्शन बनाएँ:

मानगो:

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

प्रकार:

db_typegoose.model("Car", CarModel.schema, "cars");

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

0

मैंने ऐसा करके इस मुद्दे को हल किया

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

चूंकि यह मुद्दा इसलिए हुआ क्योंकि मॉडल को दूसरी बार कॉल किया गया था। प्रयास करें ब्लॉक ब्लॉक में अपने मॉडल कोड को लपेटकर इस समस्या को हल करें। टाइपस्क्रिप्ट कोड इस प्रकार है -

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

इसी तरह आप js में भी कोड लिख सकते हैं।


-2

आप एक ही चर नाम "user" के साथ mongoose.model का उपयोग check.js और insert.js में कर रहे हैं।


-4

यदि आप एक्सप्रेस-वे के साथ काम कर रहे हैं, तो आपको अपने मॉडल की परिभाषा app.get () से बाहर ले जाने की आवश्यकता हो सकती है, इसलिए यह केवल एक बार कहा जाता है जब स्क्रिप्ट को त्वरित किया जाता है।


इसका मतलब यह नहीं है, मानस मॉडल केवल एक बार परिभाषित किया जाता है जब तक कि नामकरण (उदाहरण के मामले) के साथ कोई समस्या नहीं है, एक बार जब इसे पहली बार कहा जाता है तो इसे आरंभीकृत किया जाता है, भविष्य के लिए बस उदाहरण प्राप्त करना चाहिए और इसे फिर से स्थापित नहीं करना चाहिए
जॉनी

यह कोई हल नहीं है।
प्रथमेश
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.