Schemat Mongoose nie został zarejestrowany dla modelu


80

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

Popełniasz błąd gdzie indziej. Powyższy kod jest ważny. Być może Post.jsgdzieś „potrzebujesz” (ing) , ale nigdy nie „eksportowałeś” modelu.
Neil Lunn

@NeilLunn ok, edytuję pytanie z moim wyjątkiem błędu, ponieważ to wszystko, co mogę z niego wyczytać. może inni mogą zobaczyć to, czego ja nie widzę
arash moeen

@Umm. Czy kiedykolwiek „eksportowałeś” tam, gdzie „wymagałeś” później? Myślę, że to jest kod, którego tu brakuje.
Neil Lunn

@NeilLunn masz na myśli w app.js? pozwól mi też umieścić kod app.js (tylko część z mangusty)
arash moeen

Jeśli jest to twój kod, to nigdy nie „eksportowałeś” modelu. Rany już trzy razy. Powinieneś to już dostać.
Neil Lunn

Odpowiedzi:


142

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

@Mark komentarz var mongoose = require ("mangusta"); oraz Komentarze i posty w podobny sposób, a następnie dodaj var Posts = require ("Posty"); bezpośrednio w plikach router.get i router.post i podobnie w przypadku komentarzy
Dhyey

Wydawało się, że rozwiązało to błąd schematu, ale teraz występuje błąd „router nie jest zdefiniowany” routes/index.js. Rozumiem, czym jest brakujący błąd odniesienia, ale pomyślałem, że nie trzeba tego tworzyć. Czy ktoś to rozumie?
gin93r

@maiamachine Czy kiedykolwiek udało Ci się uruchomić samouczek Thinkster? Pracowałem nad tym od około tygodnia i utknąłem z przypadkowymi problemami w każdym miejscu. Jest jakaś szansa, że ​​mógłbyś opublikować działający kod na jsFiddle czy coś?
Travis Heeter

@ user8264: Jak zrealizować swoją koncepcję dla dynamicznie tworzonego modelu schematu?
Pappa S

48

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'
}

2
naprawiono mój problem :)
midhun k

32

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

2
To rozwiązanie rozwiązało mój problem! findOne({}).populate({ path: 'created_by', model: User })
Ricardo Silva

Zrobiłem to dla mnie. Dzięki, bud
Aleks

@ user3616725: Jak zrealizować swoją koncepcję dla dynamicznie tworzonego modelu schematu?
Pappa S

1
@PappaS Dopóki znasz NAZWĘ modelu, możesz podać nazwę modelu, a nie instancję modelu: Customer.findOne({}).populate({ path: 'created_by', model: 'User' })ALE modele muszą być już zarejestrowane w tej samej instancji mangusty.
user3616725

13

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 refnie ma stringwartości typu, teraz odnosi się do Commentschematu.


1
Wielkie dzięki, to naprawdę był dla mnie jedyny sposób - po wypróbowaniu dziesiątek wariantów - aby łatwo to działało.
Stefan Walther

Jak wdrożyć koncepcję dynamicznie tworzonego modelu schematu?
Pappa S

4

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


Miałem ten sam problem, gdy model odnosi się do innego modelu mangusty. Zainspirowany Twoją odpowiedzią, zmień nazwę kolekcji MongoDB na prawidłową, do której odnosi się moja obecna kolekcja MongoDB. Problem rozwiązany. Dziękuję Ci bardzo.
GoodApple

3

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


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

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

1

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

});


1

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 Taskjak Tasksmój problem został rozwiązany


0

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

0

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 zamiast User). 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' } })

0

W moim przypadku ten problem, ponieważ nie włączyłem modelu ani modelu referencyjnego do aplikacji. Więc powinieneś wymagać Post modeli Comment modelw swojej aplikacji węzła.


0

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".


0

Mam również ten sam problem, ale rozwiązałem go, usuwając module.exports

module.exports = mongoose.model ('user', userSchema); // usuń module.exports
i użyj 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

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


0

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

0

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 connpodczas inicjowania połączenia

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

Zauważ, że dodałem Devicedo połączenia.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.