Mongoose Schema wurde nicht für das Modell registriert

80

Ich lerne den mittleren Stapel und wenn ich versuche, den Server mit zu starten

npm start

Ich bekomme eine Ausnahme, die besagt:

schema hasn't been registered for model 'Post'. Use mongoose.model(name, schema)

Hier ist mein Code in /models/Posts.js

var mongoose = require('mongoose');

var PostSchema = new mongoose.Schema({
    title: String,
    link: String, 
    upvotes: { type: Number, default: 0 },
    comments: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Comment' }]
});

mongoose.model('Post', PostSchema);

Wie ich sehen kann, sollte das Schema für das Modell 'Post' registriert sein, aber was kann möglicherweise dazu führen, dass die Ausnahme ausgelöst wird?

Danke im Voraus.

Bearbeiten: Hier ist der Ausnahmefehler

/home/arash/Documents/projects/personal/flapper-news/node_modules/mongoose/lib/index.js:323
  throw new mongoose.Error.MissingSchemaError(name);
        ^
MissingSchemaError: Schema hasn't been registered for model "Post".
Use mongoose.model(name, schema)

und hier ist der app.js-Code mit der Mungo-Initialisierung:

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/news');
require('./models/Posts');
require('./models/Comments');

vor der Zeile:

app.use('/', routes);
Arash Moeen
quelle
Du machst woanders einen Fehler. Der obige Code ist gültig. Vielleicht "benötigen" Sie Post.jsirgendwo etwas, aber Sie haben das Modell nie "exportiert".
Neil Lunn
@NeilLunn ok Ich werde die Frage mit meinem Ausnahmefehler bearbeiten, da das alles ist, was ich daraus lesen kann. Vielleicht können andere sehen, was ich nicht sehen kann
Arash Moeen
@Umm. Haben Sie jemals "exportiert", wo Sie später "benötigt" haben? Ich denke, das ist der Code, der hier fehlt.
Neil Lunn
@NeilLunn meinst du in der app.js? Lassen Sie mich auch den app.js-Code eingeben (nur Mungo-Teil)
Arash Moeen
Wenn diese ID Ihren Code enthält, haben Sie das Modell nie "exportiert". Meine Güte, jetzt dreimal. Sie sollten dies jetzt bekommen.
Neil Lunn

Antworten:

142

Es ist kein Problem beim Modellexport. Ich hatte das gleiche Problem.

Das eigentliche Problem ist, dass Anweisungen für die Modelle erforderlich sind

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/news');
require('./models/Posts');
require('./models/Comments');

waren unter den Routenabhängigkeiten. Verschieben Sie einfach die mongoDB-Abhängigkeiten über die Routenabhängigkeiten. So sollte es aussehen:

// MongoDB
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/news');
require('./models/Posts');
require('./models/Comments');

var routes = require('./routes/index');
var users = require('./routes/users');

var app = express();
user8264
quelle
@Mark Kommentar der var mongoose = require ("mongoose"); und Kommentare und Beiträge ähnlich und fügen Sie dann var Posts = require ("Posts") hinzu; direkt in der router.get und router.post, und ähnlich für Kommentare
Dhyey
Dies schien den Schema-Fehler zu beheben, aber jetzt gibt es einen Fehler "Router ist nicht definiert" in routes/index.js. Ich verstehe, was ein fehlender Referenzfehler ist, aber ich dachte, dass dies nicht instanziiert werden muss. Hat jemand das verstanden?
Gin93r
@maiamachine Hast du jemals das Thinkster-Tutorial zum Laufen gebracht? Ich arbeite seit ungefähr einer Woche daran und habe überall zufällige Probleme. Gibt es eine Chance, dass Sie Arbeitscode auf jsFiddle veröffentlichen oder so?
Travis Heeter
@ user8264: Wie implementiere ich mein Konzept für ein dynamisch erstelltes Schemamodell?
Pappa S
46

Wenn jemand (wie ich) das Problem nicht mit der richtigen Antwort beheben kann, versuchen Sie, die Erstellung des Schemas zu überprüfen. Ich habe den 'ref' als 'User' geschrieben, aber der richtige war 'user'.

Falsch:

createdBy: {
    type: Schema.Types.ObjectId,
    ref: 'User'
}

Richtig:

createdBy: {
    type: Schema.Types.ObjectId,
    ref: 'user'
}
Rafael Grilli
quelle
2
mein Problem behoben :)
Midhun k
30

WENN SIE MEHRERE mongoDB-VERBINDUNGEN VERWENDEN


Beachten Sie, dass Sie bei Verwendung von .populate () das Modell angeben MÜSSEN, da Mungo nur Modelle auf derselben Verbindung "findet". dh wo:

var db1 = mongoose.createConnection('mongodb://localhost:27017/gh3639');
var db2 = mongoose.createConnection('mongodb://localhost:27017/gh3639_2');
var userSchema = mongoose.Schema({
  "name": String,
  "email": String
});

var customerSchema = mongoose.Schema({
  "name" : { type: String },
  "email" : [ String ],
  "created_by" : { type: mongoose.Schema.Types.ObjectId, ref: 'users' },
});

var User = db1.model('users', userSchema);
var Customer = db2.model('customers', customerSchema);

Richtig:

Customer.findOne({}).populate('created_by', 'name email', User)

oder

Customer.findOne({}).populate({ path: 'created_by', model: User })

Falsch (erzeugt den Fehler "Schema wurde nicht für Modell registriert"):

Customer.findOne({}).populate('created_by');
user3616725
quelle
2
Diese Lösung hat mein Problem behoben! findOne({}).populate({ path: 'created_by', model: User })
Ricardo Silva
Hab es für mich getan. Danke Kumpel
Aleks
@ user3616725: Wie implementiere ich mein Konzept für ein dynamisch erstelltes Schemamodell?
Pappa S
1
@PappaS Solange Sie den Modellnamen kennen, können Sie den Modellnamen anstelle einer Modellinstanz eingeben: Customer.findOne({}).populate({ path: 'created_by', model: 'User' })ABER die Modelle müssen bereits auf derselben Mungo-Instanz registriert sein.
user3616725
11

Ich habe den folgenden Ansatz verwendet, um das Problem zu lösen

const mongoose = require('mongoose');
const Comment = require('./comment');

const PostSchema = new mongoose.Schema({
            title: String,
            link: String, 
            upvotes: { type: Number, default: 0 },
            comments: [{ type: mongoose.Schema.Types.ObjectId, ref: Comment }]
        });
mongoose.model('Post', PostSchema);

Bitte schauen Sie hier ref haben Sie keinen stringTypwert, jetzt bezieht es sich auf das CommentSchema.

kuldipem
quelle
1
Vielen Dank, das war wirklich der einzige Weg für mich - nachdem ich Dutzende von Varianten ausprobiert hatte - es einfach zum Laufen zu bringen.
Stefan Walther
Wie implementiere ich Ihr Konzept für ein dynamisch erstelltes Schemamodell?
Pappa S
4

Dieser Fehler tritt auch auf, wenn wir falsche Referenzen (ref) zwischen Mungomodellen erstellen.

In meinem Fall bezog ich mich auf den Dateinamen anstelle des Modellnamens.

z.B:

const userModel = mongoose.model("user", userSchema);

Wir sollten uns auf 'Benutzer' (Modellname) anstelle von 'Benutzer' (Dateiname) beziehen.

100RaBH
quelle
Ich hatte das gleiche Problem, während sich ein Modell auf ein anderes Mungomodell bezieht. Wechseln Sie, inspiriert von Ihrer Antwort, zum richtigen MongoDB-Sammlungsnamen, auf den sich meine aktuelle MongoDB-Sammlung bezieht. Problem gelöst. Vielen Dank.
GoodApple
2
.\nodeapp\node_modules\mongoose\lib\index.js:452
      throw new mongoose.Error.MissingSchemaError(name);
      ^
MissingSchemaError: Schema hasn't been registered for model "users".
Use mongoose.model(name, schema)
    at new MissingSchemaError

Ich habe diesen Fehler behoben, wenn setTimeout auf server.js verwendet wurde

mongoose.connect(env.get('mongodb.uri'), { useNewUrlParser: true })
  .then(() => logger.info("MongoDB successfully connected"))
  .catch(err => logger.error(err));
app.use(passport.initialize());
setTimeout(function() {
  require("./src/utils/passport")(passport);
}, 3000);
Visv M.
quelle
2

Hier ist https://mongoosejs.com/docs/populate.html#cross-db-populate

Es heißt, wir müssen das Modell als drittes Argument übergeben.

Zum Beispiel

//Require User Model
const UserModel = require('./../models/User');
//Require Post Model
const PostModel = require('./../models/Post');
const posts = await PostModel.find({})
            .select('-__v')
            .populate({
              path: 'user',
              select: 'name -_id',
              model: UserModel
            });
//or 
const posts = await PostModel.find({})
            .select('-__v')
            .populate('user','name', UserModel);

Nikhil Vats
quelle
1

Ich hatte auch das gleiche Problem. Die Lösung für mein Problem bestand darin, den ref-Parameter zu untersuchen, der einen anderen Namen hatte als das Modell, das ich tatsächlich exportierte, und daher wurde kein solches Modell gefunden.

userSchema.virtual('tasks', {
    ref: 'Task',
    localField: '_id',
    foreignField: 'owner'
})
  

Was ich tatsächlich exportiert hatte, war:

const Tasks = mongoose.model('Tasks', taskSchema)

module.exports = Tasks

Nach der Behebung des Taskals Tasksmein Problem gelöst wurde

Akash Das
quelle
0

Auf die Antwort von Rafael Grilli oben eingehen,

Richtig:

var HouseSchema = new mongoose.Schema({
  date: {type: Date, default:Date.now},
  floorplan: String,
  name:String,
  house_id:String,
  addressLine1:String,
  addressLine2:String,
  city:String,
  postCode:String,
  _locks:[{type: Schema.Types.ObjectId, ref: 'xxx'}] //ref here refers to the first parameter passed into mongoose.model()
});
var House = mongoose.model('xxx', HouseSchema, 'houseschemas');
Russell Elfenbein
quelle
0

Sie sollten auch überprüfen, ob Ihre Datenbank keine fehlerhaften Daten enthält. Am Ende hatte ich ein Dokument, das die Kleinbuchstabenversion des referenzierten Modells enthielt ( useranstelle vonUser ). Dies verursacht den Fehler und ist unglaublich schwer zu finden.

Einfach mit einer schnellen Mongo-Abfrage zu beheben:

db.model.updateMany({ approvedByKind: 'user' }, { $set: { approvedByKind: 'User' } })
Developius
quelle
0

In meinem Fall dieses Problem, weil ich das Modell oder das Referenzmodell nicht in die Anwendung aufgenommen habe. Sie sollten also benötigt Post modelund Comment modelin Ihrer Knotenanwendung.

Thai Ha
quelle
0

Verweisen Sie beim Erstellen eines neuen Modells auf denselben Namen, auf den Sie im Modellnamen verweisen.

Zum Beispiel: Wenn ich ein Mungomodell habe wie:

var Post = mongoose.model("post",postSchema);

Dann muss ich mich schriftlich auf die Postsammlung beziehen ref:"post".

Drumil
quelle
0

Ich habe auch das gleiche Problem, aber ich habe es gelöst, indem ich module.exports entfernt habe

module.exports = mongoose.model ('user', userSchema); // entferne module.exports und benutze like :: mongoose.model
('user', userSchema);

const mongoose = require('mongoose');
const ObjectId = require('mongoose').ObjectId;

var userSchema = new mongoose.Schema({
    Password: { type: String },  
    Email: { type: String, required: 'This field is required.', unique:true },  
    songs: [{ type: ObjectId, ref: 'Songs'}]
});

// Custom validation for email
userSchema.path('Email').validate((val) => {
    emailRegex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    return emailRegex.test(val);
}, 'Invalid e-mail.');

// module.exports = mongoose.model('user', userSchema);  // remove 'module.exports ='
mongoose.model('user', userSchema); // resolved issue
HSP
quelle
0

Das Problem liegt bei den Refs. Stellen Sie immer sicher, dass die Refs auf den Namen verweisen, den Sie aus den Modellen exportieren.

// Modell

const Task = mongoose.model('**Tasks**', taskSchema);

// Refs

userSchema.virtual('tasks', {
ref: '**Tasks**',
localField: '_id', // field in current model
foreignField: 'owner' // corresponding field in other model

});

ajay
quelle
0

Mein Problem wurde mit dem folgenden Problem gelöst

adminModel.findById (req.params.id) .populate ({Pfad: "Benutzer", Modell: userModel // Name der Benutzersammlung})

Hemant
quelle
0

Ich wollte nur hinzufügen, dass ich beim Importieren des Schemas Destrukturierung verwendet habe, wodurch es fehlgeschlagen ist.

Richtig

var intakeSchema = require('../config/models/intake')

Falsch

var { intakeSchema } = require('../config/models/intake')
Phillyp Henning
quelle