Uczę się średniego stosu i kiedy próbuję uruchomić serwer za pomocą
npm start
Mam wyjątek, który mówi, że:
schema hasn't been registered for model 'Post'. Use mongoose.model(name, schema)
tutaj jest mój kod w /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);
jak widzę schemat powinien być zarejestrowany dla modelu „Post”, ale co może być przyczyną wyrzucenia wyjątku?
Z góry dziękuję.
Edycja: Oto błąd wyjątku
/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)
a oto kod app.js z inicjalizacją mongoose:
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/news');
require('./models/Posts');
require('./models/Comments');
przed linią:
app.use('/', routes);
Post.js
gdzieś „potrzebujesz” (ing) , ale nigdy nie „eksportowałeś” modelu.Odpowiedzi:
Nie ma problemu z eksportem modelu. Miałem ten sam problem.
Prawdziwym problemem jest to, że modele wymagają zestawień
var mongoose = require('mongoose'); mongoose.connect('mongodb://localhost/news'); require('./models/Posts'); require('./models/Comments');
były poniżej zależności tras. Po prostu przenieś zależności mongoDB powyżej zależności tras. Tak to powinno wyglądać:
// 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();
źródło
routes/index.js
. Rozumiem, czym jest brakujący błąd odniesienia, ale pomyślałem, że nie trzeba tego tworzyć. Czy ktoś to rozumie?Jeśli komuś nie udało się tego naprawić podejściem poprawnej odpowiedzi (tak jak ja), spróbuj przyjrzeć się tworzeniu schematu. Napisałem „ref” jako „User”, ale poprawne było „user”.
Źle:
createdBy: { type: Schema.Types.ObjectId, ref: 'User' }
Poprawny:
createdBy: { type: Schema.Types.ObjectId, ref: 'user' }
źródło
JEŚLI UŻYWASZ WIELU POŁĄCZEŃ mongoDB
uważaj, gdy używasz .populate () MUSISZ podać model, ponieważ mangusta będzie "znajdować" tylko modele na tym samym połączeniu. czyli gdzie:
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);
Poprawny:
Customer.findOne({}).populate('created_by', 'name email', User)
lub
Customer.findOne({}).populate({ path: 'created_by', model: User })
Niepoprawnie (powoduje błąd „Schemat nie został zarejestrowany dla modelu”):
Customer.findOne({}).populate('created_by');
źródło
findOne({}).populate({ path: 'created_by', model: User })
Customer.findOne({}).populate({ path: 'created_by', model: 'User' })
ALE modele muszą być już zarejestrowane w tej samej instancji mangusty.Do rozwiązania problemu zastosowałem następujące podejście
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);
Proszę spojrzeć, tutaj
ref
nie mastring
wartości typu, teraz odnosi się doComment
schematu.źródło
Ten błąd pojawia się również, gdy tworzymy błędne odniesienia (ref) między modelami mangusty.
W moim przypadku odnosiłem się do nazwy pliku zamiast nazwy modelu.
na przykład:
const userModel = mongoose.model("user", userSchema);
Powinniśmy odnosić się do „użytkownika” (nazwa modelu) zamiast „Użytkownik” (nazwa pliku);
źródło
Oto https://mongoosejs.com/docs/populate.html#cross-db-populate
Mówi, że musimy przekazać model jako trzeci argument.
Np
//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);
źródło
.\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
Ten błąd został rozwiązany, gdy używam setTimeout na serwerze 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);
źródło
Problem dotyczy referencji, zawsze upewnij się, że odwołujesz się do dowolnej nazwy, którą eksportujesz z modeli.
// Model
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
});
źródło
Miałem też ten sam problem. Rozwiązaniem mojego problemu było przyjrzenie się parametrowi ref, który miał inną nazwę w porównaniu z modelem, który faktycznie eksportowałem, a zatem nie znaleziono takiego modelu.
userSchema.virtual('tasks', { ref: 'Task', localField: '_id', foreignField: 'owner' })
Podczas gdy to, co faktycznie wyeksportowałem, to: -
const Tasks = mongoose.model('Tasks', taskSchema) module.exports = Tasks
Po rektyfikacji
Task
jakTasks
mój problem został rozwiązanyźródło
Rozwijając odpowiedź Rafaela Grilli powyżej,
Poprawny:
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');
źródło
Powinieneś również sprawdzić, czy nie masz brudnych danych w swojej bazie danych. Skończyło się na dokumencie zawierającym małą literę wersji modelu, do którego się odwołuje (
user
zamiastUser
). To powoduje błąd i jest niezwykle trudne do wyśledzenia.Łatwe do naprawienia dzięki szybkiemu zapytaniu mongo:
db.model.updateMany({ approvedByKind: 'user' }, { $set: { approvedByKind: 'User' } })
źródło
W moim przypadku ten problem, ponieważ nie włączyłem modelu ani modelu referencyjnego do aplikacji. Więc powinieneś wymagać
Post model
iComment model
w swojej aplikacji węzła.źródło
Podczas tworzenia nowego modelu odwołaj się do tej samej nazwy, którą odwołujesz się do nazwy modelu.
Na przykład: jeśli mam model mangusty taki jak:
var Post = mongoose.model("post",postSchema);
Następnie muszę odnieść się do zbierania postów poprzez pisanie
ref:"post"
.źródło
Mam również ten sam problem, ale rozwiązałem go, usuwając module.exports
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
źródło
Mój problem został rozwiązany za pomocą poniższego
adminModel.findById (req.params.id) .populate ({ścieżka: "użytkownicy", model: userModel // nazwa zbioru użytkowników})
źródło
Chciałem tylko dodać, że podczas importowania schematu używałem destrukturyzacji, co powodowało jego niepowodzenie.
Poprawny
var intakeSchema = require('../config/models/intake')
Błędny
var { intakeSchema } = require('../config/models/intake')
źródło
Nie nadajesz modelowi żadnej wartości
W moim przypadku korzystałem z modelu, dla którego nie zaktualizowałem się podczas nawiązywania połączenia z MongoDB.
Więc miałem coś takiego
const Device = require('../../models/device')
// make use of Device
z tym połączeniem
conn = await mongo.createConnection(conn, [JobApplication, Job, User])
Naprawić
Musisz dodać model do
conn
podczas inicjowania połączeniaconn = await mongo.createConnection(conn, [JobApplication, Job, User, Device])
Zauważ, że dodałem
Device
do połączenia.źródło