Mongoose Schema не зареєстрована для моделі


80

Я вивчаю середній стек і коли намагаюся запустити сервер за допомогою

npm start

Я отримую виняток, який говорить:

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

ось мій код всередині /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);

як я бачу, схема повинна бути зареєстрована для моделі "Пошта", але що може спричинити виникнення винятку?

Заздалегідь спасибі.

Редагувати: Ось помилка винятку

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

і ось код app.js з ініціалізацією мангуста:

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

перед рядком:

app.use('/', routes);

Ви десь помиляєтесь. Наведений код дійсний. Можливо, вас Post.jsдесь "вимагають" , але ви ніколи не "експортували" модель.
Ніл Ланн,

@NeilLunn нормально Я відредагую запитання з моєю помилкою виключення, тому що це все, що я можу прочитати з нього. можливо, інші можуть побачити те, що я не бачу
arash moeen

@ Umm. Ви коли-небудь пізніше "експортували" туди, де "вимагали"? Я думаю, що тут відсутній код.
Ніл Ланн,

@NeilLunn, ви маєте на увазі в app.js? дозвольте мені також розмістити код app.js (лише частина мангуста)
arash moeen

Якщо це ідентифікатор вашого коду, ви ніколи не "експортували" модель. Гай, три рази. Ви повинні отримати це зараз.
Ніл Ланн,

Відповіді:


142

Це не проблема з експортом моделі. У мене була та сама проблема.

Справжнє питання полягає в тому, що потрібні заяви для моделей

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

були нижче залежностей маршрутів. Просто перемістіть залежності mongoDB над залежностями маршрутів. Ось як це повинно виглядати:

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

@ Позначити коментар var mongoose = require ("мангуст"); і Коментарі та повідомлення аналогічним чином, а потім додайте var Posts = require ("Публікації"); безпосередньо всередині router.get та router.post, і так само для Коментарів
Dhyey

Це, здавалося, вирішило помилку схеми, але тепер у routes/index.js. Помилка "маршрутизатор не визначений" . Я розумію, що таке відсутня помилка посилання, але я думав, що це не потрібно інстанціювати .. хтось отримує це?
gin93r

@maiamachine Чи отримували ви коли-небудь підручник з Thinkster для роботи? Я працюю над цим близько тижня і повсюдно застряг у випадкових питаннях. Будь-який шанс ви можете розмістити робочий код на jsFiddle чи щось інше?
Тревіс Хітер

@ user8264: Як реалізувати свою концепцію для динамічно створеної моделі схеми?
Pappa S

48

Якщо хтось не зміг це виправити з підходом правильної відповіді (як я), спробуйте поглянути на створення схеми. Я написав "ref" як "User", але правильним було "user".

Неправильно:

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

Правильно:

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

2
виправлено мою проблему :)
midhun k

32

ЯКЩО ВИ ВИКОРИСТОВУЄТЕ МНОГО ПІДКЛЮЧЕНЬ mongoDB


майте на увазі, що при використанні .populate () ви ПОВИННІ надати модель, оскільки мангуст лише "знайде" моделі на тому самому з'єднанні. тобто де:

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

Правильно:

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

або

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

Неправильно (видає помилку "схема не була зареєстрована для моделі"):

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

2
Це рішення виправило мою проблему! findOne({}).populate({ path: 'created_by', model: User })
Рікардо Сільва

Зробив це для мене. Спасибі
Алекс

@ user3616725: Як реалізувати свою концепцію для динамічно створеної моделі схеми?
Pappa S

1
@PappaS Поки ви знаєте ІМЯ моделі, ви можете вставити ім'я моделі, а не екземпляр моделі: Customer.findOne({}).populate({ path: 'created_by', model: 'User' })АЛЕ моделі повинні бути вже зареєстровані в тому ж екземплярі мангуста.
user3616725

13

Для вирішення проблеми я використав наступний підхід

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

Будь ласка, подивіться, тут refнемає stringзначення типу, тепер це стосується Commentсхеми.


1
Дуже багато, це справді був єдиним способом для мене - після випробування десятків варіантів - змусити його легко працювати.
Стефан Вальтер

Як реалізувати свою концепцію для динамічно створеної моделі схеми?
Pappa S

4

Ця помилка також з’являється, коли ми створюємо неправильні посилання (ref) між моделями мангуста.

У моєму випадку я посилався на ім'я файлу, а не на ім'я моделі.

наприклад:

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

Ми повинні посилатися на "користувач" (ім'я моделі) замість "Користувач" (ім'я файлу);


У мене була та сама проблема, коли модель посилається на іншу модель мангуста. Натхненний вашою відповіддю, змініть правильну назву колекції MongoDB, на яку посилається моя поточна колекція MongoDB. Проблема вирішена. Дуже дякую.
GoodApple

3

Ось https://mongoosejs.com/docs/populate.html#cross-db-populate

Там сказано, що ми повинні передавати модель як третій аргумент.

Наприклад,

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

Я отримав цю помилку, усунуту під час використання setTimeout на 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

Проблема полягає в посиланнях, завжди переконайтеся, що посилання на них посилаються на будь-яке ім’я, яке ви експортуєте з моделей.

// Модель

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

// Посилання

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

});


1

Я теж стикався з тією ж проблемою. Рішенням моєї проблеми було розглядання параметра ref, який мав іншу назву порівняно з моделлю, яку я фактично експортував, а отже, такої моделі не знайдено.

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

Тоді як я фактично експортував:

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

module.exports = Tasks

Після виправлення Taskяк Tasksмоя проблема була вирішена


0

Розробляючи відповідь Рафаеля Гриллі вище,

Правильно:

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

Також слід перевірити, чи немає у вашій базі даних брудних даних. У підсумку я отримав документ, що містить малу версію вказаної моделі ( userзамість User). Це спричиняє помилку та неймовірно важко відстежити.

Легко виправити за допомогою швидкого запиту mongo:

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

0

У моєму випадку це питання, оскільки я не включив модель чи модель ref в додаток. Таким чином, ви повинні вимагати Post modelі Comment modelу вашому додатку вузла.


0

Посилайтеся на те саме ім’я, яке ви позначаєте в назві моделі під час створення нової моделі.

Наприклад: якщо у мене є модель мангуста, як:

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

Тоді я маю посилатися на колекцію дописів письмово ref:"post".


0

Я також стикався з такою ж проблемою, але вирішив, видаливши module.exports

module.exports = mongoose.model ('користувач', userSchema); // видалити module.exports
і використовувати як :: 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

Моєю проблемою було розібратися за допомогою нижче

adminModel.findById (req.params.id) .populate ({шлях: "користувачі", модель: userModel // ім'я колекції користувачів})


0

Просто хотів додати, що для мене я використовував деструктуризацію під час імпорту схеми, яка спричинила її збій.

Правильно

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

Невірно

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

0

Ви не надаєте моделі жодної цінності

У моєму випадку я використовував модель, для якої я не оновлювався під час встановлення з'єднання MongoDB.

Отже, у мене було щось подібне

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

з цим зв’язком

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

Виправити

Ви повинні додати модель до, connколи ініціюєте підключення

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

Зверніть увагу, що я додав Deviceз'єднання.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.