Mongoose Schema no se ha registrado para el modelo


80

Estoy aprendiendo la pila media y cuando intento iniciar el servidor usando

npm start

Recibo una excepción que dice que:

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

aquí está mi código dentro de /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);

como puedo ver, el esquema debe registrarse para el modelo 'Publicar', pero ¿qué puede estar causando que se lance la excepción?

Gracias por adelantado.

Editar: aquí está el error de excepción

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

y aquí está el código de app.js con la inicialización de mangosta:

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

antes de la línea:

app.use('/', routes);

Estás cometiendo un error en otro lugar. El código anterior es válido. Quizás esté "requiriendo" (ing) en Post.jsalguna parte, pero nunca "exportó" el modelo.
Neil Lunn

@NeilLunn ok Editaré la pregunta con mi error de excepción, porque eso es todo lo que puedo leer de ella. tal vez otros puedan ver lo que yo no puedo ver
arash moeen

@Umm. ¿Alguna vez "exportó" donde lo "requirió" más tarde? Creo que ese es el código que falta aquí.
Neil Lunn

@NeilLunn, ¿te refieres a app.js? déjame poner el código app.js también (solo parte de la mangosta)
arash moeen

Si eso identifica su código, entonces nunca "exportó" el modelo. Caray Tres veces ahora. Deberías conseguir esto ahora.
Neil Lunn

Respuestas:


142

No es un problema con la exportación de modelos. Tuve el mismo problema.

El problema real es que requieren declaraciones para los modelos.

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

estaban por debajo de las dependencias de rutas. Simplemente mueva las dependencias de mongoDB por encima de las dependencias de rutas. Así es como debería verse:

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

@Mark comenta la var mongoose = require ("mangosta"); y Comentarios y Publicaciones de manera similar y luego agregue var Publicaciones = require ("Publicaciones"); directamente dentro de router.get y router.post, y de manera similar para Comentarios
Dhyey

Esto pareció resolver el error de esquema, pero ahora hay un error de "enrutador no definido" routes/index.js. Entiendo lo que es un error de referencia faltante, pero pensé que no era necesario crear una instancia. ¿Alguien entendió esto?
gin93r

@maiamachine ¿Alguna vez consiguió que funcionara el tutorial de Thinkster? He estado trabajando en eso durante aproximadamente una semana y he estado atascado con problemas aleatorios por todas partes. ¿Alguna posibilidad de que pueda publicar código de trabajo en jsFiddle o algo así?
Travis Heeter

@ user8264: ¿Cómo implementar su concepto para el modelo de esquema creado dinámicamente?
Pappa S

48

Si alguien no pudo solucionarlo con el enfoque de la respuesta correcta (como yo), intente observar la creación del esquema. Escribí la 'ref' como 'Usuario', pero la correcta era 'usuario'.

Incorrecto:

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

Correcto:

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

2
solucionó mi problema :)
midhun k

32

SI UTILIZA MÚLTIPLES CONEXIONES mongoDB


tenga en cuenta que cuando utilice .populate () DEBE proporcionar el modelo, ya que mongoose solo "encontrará" modelos en la misma conexión. es decir, donde:

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

Correcto:

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

o

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

Incorrecto (produce el error "el esquema no se ha registrado para el modelo"):

Customer.findOne({}).populate('created_by');

2
¡Esta solución solucionó mi problema! findOne({}).populate({ path: 'created_by', model: User })
Ricardo Silva

Lo hice por mí. Gracias amigo
Aleks

@ user3616725: ¿Cómo implementar su concepto para el modelo de esquema creado dinámicamente?
Pappa S

1
@PappaS Siempre que conozca el NOMBRE del modelo, puede pasar el nombre del modelo, en lugar de una instancia del modelo: Customer.findOne({}).populate({ path: 'created_by', model: 'User' })PERO los modelos ya deben estar registrados en la misma instancia de mangosta.
user3616725

13

Usé el siguiente enfoque para resolver el problema

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

Mire, aquí refno tiene stringvalor de tipo, ahora se refiere al Commentesquema.


1
Muchas gracias, esa era realmente la única forma para mí, después de probar docenas de variantes, para que funcionara fácilmente.
Stefan Walther

¿Cómo implementar su concepto para el modelo de esquema creado dinámicamente?
Pappa S

4

Este error también aparece cuando creamos referencias incorrectas (ref) entre modelos de mangosta.

En mi caso, me refería al nombre del archivo en lugar del nombre del modelo.

p.ej:

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

Deberíamos referirnos a 'usuario' (nombre del modelo) en lugar de 'Usuario' (nombre de archivo);


Tuve el mismo problema mientras que un modelo se refiere a otro modelo de mangosta. Inspirado por su respuesta, cambie al nombre correcto de la colección MongoDB al que se refiere mi colección MongoDB actual. Problema resuelto. Muchas gracias.
GoodApple

3

Aquí está https://mongoosejs.com/docs/populate.html#cross-db-populate

Dice que tenemos que pasar el modelo como tercer argumento.

Por ejemplo

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


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

Obtuve este error resuelto cuando uso setTimeout en server.js

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

1

El problema es con las referencias, siempre asegúrese de referir las referencias a cualquier nombre que esté exportando de los modelos.

// Modelo

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

});


1

También me enfrentaba al mismo problema. La solución a mi problema fue mirar el parámetro ref que tenía un nombre diferente en comparación con el modelo que realmente estaba exportando y, por lo tanto, no se encontró tal modelo.

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

Mientras que lo que realmente había exportado era: -

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

module.exports = Tasks

Después de rectificar el Taskcomo Tasksse resolvió mi problema


0

Desarrollando la respuesta de Rafael Grilli anterior,

Correcto:

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

0

También debe verificar que no tenga datos sucios en su base de datos. Terminé con un documento que contenía la versión en minúsculas del modelo al que se hace referencia (en userlugar de User). Esto causa el error y es increíblemente difícil de localizar.

Fácil de solucionar con una consulta rápida de mongo:

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

0

En mi caso, este problema porque no he incluido el modelo o el modelo de referencia en la aplicación. Por lo que debería ser requerido Post modely Comment modelen su aplicación de nodo.


0

Refiera el mismo nombre que hace referencia en el nombre del modelo al crear un nuevo modelo.

Por ejemplo: si tengo un modelo de mangosta como:

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

Entonces tengo que referirme a la colección de publicaciones por escrito ref:"post".


0

También me enfrento al mismo problema, pero lo resolví eliminando module.exports

module.exports = mongoose.model ('usuario', userSchema); // eliminar module.exports
y usar 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

0

Mi problema se resolvió usando el siguiente

adminModel.findById (req.params.id) .populate ({ruta: "usuarios", modelo: userModel // Nombre de la colección de usuarios})


0

Solo quería agregar que para mí estaba usando desestructuración al importar el esquema que estaba causando que fallara.

Correcto

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

Incorrecto

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

0

No le estás dando ningún valor al modelo

En mi caso, estaba usando un modelo para el que no actualicé al hacer la conexión MongoDB.

Entonces, tuve algo como

const Device = require('../../models/device')
// make use of Device

con esta conexión

conn = await mongo.createConnection(conn,
      [JobApplication, Job, User])

Reparar

Tienes que agregar el modelo al connal iniciar la conexión

conn = await mongo.createConnection(conn,
      [JobApplication, Job, User, Device])

Tenga en cuenta que agregué Devicea la conexión.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.