Схема Mongoose не зарегистрирована для модели


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

как я вижу, схема должна быть зарегистрирована для модели «Post», но что может быть причиной возникновения исключения?

Заранее спасибо.

Изменить: вот ошибка исключения

/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, хорошо, я отредактирую вопрос с моей ошибкой исключения, потому что это все, что я могу прочитать. может быть, другие могут видеть то, что не вижу я
— Араш Моен

@ Умм. Вы когда-нибудь «экспортируете» то, что вам «требовалось» позже? Я думаю, что это код, который здесь отсутствует.
— Нил Ланн

@NeilLunn ты имеешь ввиду в app.js? позвольте мне также поставить код app.js (только часть мангуста)
— arash moeen 08

Если это идентификатор вашего кода, вы никогда не «экспортировали» модель. Господи, уже три раза. Вы уже должны это получить.
— Нил Ланн

Ответы:


142

Это не проблема с экспортом модели. Я была такая же проблема.

Настоящая проблема в том, что операторы require для моделей

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

@Mark прокомментируйте var mongoose = require ("mongoose"); и Комментарии и Сообщения аналогичным образом, а затем добавьте var Posts = require ("Posts"); непосредственно внутри router.get и router.post, и аналогично для комментариев
— Dhyey 01

Казалось, что это решило ошибку схемы, но теперь в ней есть ошибка «маршрутизатор не определен» routes/index.js. Я понимаю, что такое ошибка отсутствия ссылки, но я подумал, что это не нужно создавать ... кто-нибудь это понял?
— gin93r

@maiamachine Вы когда-нибудь заставляли работать учебник Thinkster? Я работал над этим около недели и постоянно сталкивался со случайными проблемами. Есть ли шанс разместить рабочий код на jsFiddle или что-то в этом роде?
— Travis Heeter

@ user8264: Как реализовать вашу концепцию для динамически создаваемой модели схемы?
— Pappa S

48

Если кто-то не смог исправить это подходом правильного ответа (как я), попробуйте взглянуть на создание схемы. Я написал «ref» как «Пользователь», но правильным было «пользователь».

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

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 03

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
и используем 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

Моя проблема была решена с помощью нижеприведенного

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.