Схема 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.