Lược đồ Mongoose chưa được đăng ký cho mô hình


80

Tôi đang tìm hiểu về ngăn xếp trung bình và khi tôi cố gắng khởi động máy chủ bằng cách sử dụng

npm start

Tôi nhận được một ngoại lệ khi nói rằng:

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

đây là mã của tôi bên trong /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);

như tôi có thể thấy lược đồ nên được đăng ký cho mô hình 'Đăng', nhưng điều gì có thể khiến ngoại lệ bị ném?

Cảm ơn trước.

Chỉnh sửa: Đây là lỗi ngoại lệ

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

và đây là mã app.js với khởi tạo mongoose:

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

trước dòng:

app.use('/', routes);

Bạn đang mắc lỗi ở một nơi khác. Đoạn mã trên là hợp lệ. Có lẽ bạn đang "yêu cầu" (ing) Post.jsở đâu đó, nhưng bạn chưa bao giờ "xuất" mô hình.
Neil Lunn

@NeilLunn ok Tôi sẽ chỉnh sửa câu hỏi với lỗi ngoại lệ của mình, vì đó là tất cả những gì tôi có thể đọc được từ nó. có thể những người khác có thể nhìn thấy những gì tôi không thể thấy
arash moeen

@ Ừm. Bạn đã bao giờ "xuất" nơi bạn "yêu cầu" sau này? Tôi nghĩ rằng đó là mã bị thiếu ở đây.
Neil Lunn

@NeilLunn ý bạn là trong app.js? hãy để tôi đặt các app.js mã quá (phần mongoose chỉ)
Arash moeen

Nếu id đó mã của bạn thì bạn không bao giờ "xuất" mô hình. Geez ba lần bây giờ. Bạn sẽ nhận được điều này ngay bây giờ.
Neil Lunn

Câu trả lời:


142

Nó không phải là một vấn đề với xuất mô hình. Tôi gặp vấn đề tương tự.

Vấn đề thực sự là yêu cầu các tuyên bố cho các mô hình

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

dưới các phụ thuộc các tuyến. Chỉ cần di chuyển các phụ thuộc mongoDB lên trên các phụ thuộc tuyến. Đây là những gì nó sẽ giống:

// 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 bình luận var mongoose = demand ("mongoose"); và Nhận xét và Bài viết tương tự và sau đó thêm var Posts = request ("Posts"); trực tiếp bên trong router.get và router.post, và tương tự cho nhận xét
Dhyey

Điều này dường như giải quyết được lỗi Schema, nhưng bây giờ có lỗi "bộ định tuyến không được xác định" routes/index.js. Tôi hiểu lỗi tham chiếu bị thiếu là gì, nhưng tôi nghĩ rằng điều này không cần phải được khởi tạo .. bất cứ ai nhận được điều này?
gin93r

@maiamachine Bạn đã bao giờ sử dụng hướng dẫn Thinkster chưa? Tôi đã làm việc trên nó trong khoảng một tuần, và bị mắc kẹt với các vấn đề ngẫu nhiên khắp nơi. Bạn có thể đăng mã làm việc trên jsFiddle hay gì đó không?
Travis Heeter

@ user8264: Làm cách nào để triển khai khái niệm của bạn cho mô hình giản đồ được tạo động?
Pappa S

48

Nếu ai đó không sửa nó bằng cách tiếp cận câu trả lời đúng (như tôi), hãy thử xem việc tạo giản đồ. Tôi đã viết 'giới thiệu' là 'Người dùng', nhưng đúng là 'người dùng'.

Sai lầm:

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

Chính xác:

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

2
đã khắc phục sự cố của tôi :)
midhun k

32

NẾU BẠN SỬ DỤNG NHIỀU KẾT NỐI mongoDB


lưu ý rằng khi sử dụng .populate (), bạn PHẢI cung cấp mô hình vì mongoose sẽ chỉ "tìm thấy" các mô hình trên cùng một kết nối. tức là ở đâu:

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

Chính xác:

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

hoặc là

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

Không chính xác (tạo ra lỗi "lược đồ chưa được đăng ký cho mô hình"):

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

2
Giải pháp này đã khắc phục sự cố của tôi! findOne({}).populate({ path: 'created_by', model: User })
Ricardo Silva

Đã làm điều đó cho tôi. Cảm ơn nụ
Aleks

@ user3616725: Làm cách nào để triển khai khái niệm của bạn cho mô hình giản đồ được tạo động?
Pappa S

1
@PappaS Miễn là bạn biết TÊN mô hình, bạn có thể dán tên mô hình, thay vì một phiên bản mô hình: Customer.findOne({}).populate({ path: 'created_by', model: 'User' })NHƯNG các mô hình phải được đăng ký trên cùng một phiên bản mongoose.
dùng3616725

13

Tôi đã sử dụng cách tiếp cận sau để giải quyết vấn đề

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

Vui lòng xem, ở đây refkhông có stringgiá trị kiểu, bây giờ nó đang đề cập đến Commentlược đồ.


1
Thx rất nhiều, đó thực sự là cách duy nhất để tôi - sau khi thử hàng tá biến thể - để nó hoạt động dễ dàng.
Stefan Walther

Làm thế nào để triển khai khái niệm của bạn cho mô hình giản đồ được tạo động?
Pappa S

4

Lỗi này cũng xuất hiện khi chúng tôi tạo sai tham chiếu (ref) giữa các mô hình mongoose.

Trong trường hợp của tôi, tôi đã đề cập đến tên tệp thay vì tên kiểu máy.

ví dụ:

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

Chúng ta nên tham chiếu đến 'người dùng' (tên kiểu máy) thay vì 'Người dùng' (tên tệp);


Tôi đã gặp vấn đề tương tự trong khi một mô hình đề cập đến một mô hình mongoose khác. Lấy cảm hứng từ câu trả lời của bạn, hãy đổi sang tên bộ sưu tập MongoDB chính xác mà bộ sưu tập MongoDB hiện tại của tôi đề cập đến. Vấn đề đã được giải quyết. Cảm ơn rât nhiều.
GoodApple

3

Đây là https://mongoosejs.com/docs/populate.html#cross-db-populate

Nó nói rằng chúng ta phải chuyển mô hình làm đối số thứ ba.

Ví dụ

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

Tôi đã giải quyết được lỗi này khi sử dụng setTimeout trên 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

Vấn đề là với các tham chiếu, hãy luôn đảm bảo tham chiếu các tham chiếu tới bất kỳ tên nào bạn đang xuất từ ​​các mô hình.

// Mô hình

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

Tôi cũng đang phải đối mặt với vấn đề tương tự. Giải pháp cho vấn đề của tôi là xem tham số ref có tên khác so với mô hình mà tôi thực sự đang xuất và do đó không tìm thấy mô hình nào như vậy.

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

Trong khi những gì tôi đã thực sự xuất là: -

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

module.exports = Tasks

Sau khi khắc phục sự cố TaskTasksvấn đề của tôi đã được giải quyết


0

Dựa trên câu trả lời của Rafael Grilli ở trên,

Chính xác:

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

Bạn cũng nên kiểm tra xem bạn không có dữ liệu bẩn trong cơ sở dữ liệu của mình. Tôi đã kết thúc với một tài liệu chứa phiên bản chữ thường của mô hình được tham chiếu ( userthay vì User). Điều này gây ra lỗi và cực kỳ khó theo dõi.

Dễ dàng sửa chữa với một truy vấn mongo nhanh chóng:

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

0

Trong trường hợp của tôi, vấn đề này do tôi chưa đưa mô hình hoặc mô hình tham chiếu vào ứng dụng. Vì vậy, bạn nên yêu cầu Post modelComment modeltrong ứng dụng nút của bạn.


0

Tham khảo cùng tên mà bạn đã đề cập trong tên mô hình khi tạo mô hình mới.

Ví dụ: nếu tôi có mô hình mongoose như:

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

Sau đó, tôi phải tham khảo bộ sưu tập bài viết thông qua viết ref:"post".


0

Tôi cũng gặp phải vấn đề tương tự nhưng tôi đã giải quyết bằng cách xóa module.exports

module.exports = mongoose.model ('user', userSchema); // gỡ bỏ module.exports
và sử dụng 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

Vấn đề của tôi đã được giải quyết bằng cách sử dụng bên dưới

adminModel.findById (req.params.id) .populate ({path: "users", model: userModel // Tên tập hợp người dùng})


0

Tôi chỉ muốn thêm rằng tôi đã sử dụng hủy cấu trúc khi nhập Lược đồ khiến nó bị lỗi.

Chính xác

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

Sai

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

0

Bạn không cung cấp cho mô hình bất kỳ giá trị nào

Trong trường hợp của tôi, tôi đang sử dụng một mô hình mà tôi chưa cập nhật khi tạo kết nối MongoDB.

Vì vậy, tôi đã có một cái gì đó giống như

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

với kết nối này

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

Sửa chữa

Bạn phải thêm mô hình vào connkhi bắt đầu kết nối

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

Lưu ý rằng tôi đã thêm vào Devicekết nối.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.