如何正确使用与Node.js Mongoose模型?

我试图用mongoose来控制我的数据库逻辑和交易。 我已经有了Schema定义,我正在导出这些模型。

不pipe怎样,当我尝试使用一个模型,它会失败,像一个消息:

return mongoose.model('Report', reportSchema); } has no method 'find' return mongoose.model('Report', reportSchema); } has no method 'find'

这是我的模型导出:

 module.exports = (function() { var mongoose = require('mongoose'), Schema = mongoose.Schema, ObjectId = Schema.ObjectId; var reportSchema = mongoose.Schema({ category: ObjectId, authorName: String, authorEmail: String, text: String, address: String, coordinates: { type: "Point", coordinates: [Number,Number] }, date: { type: Date, default: new Date() }, comments: Array }); return mongoose.model('Report', reportSchema); }); 

这就是我的控制器function是如何使用mongoose编码的:

 module.exports = (function() { var mongoose = require('mongoose'); var Report = require('../models/Report'); var Category = require('../models/Category'); function _getReports (request,response,next) { var take = request.query.take; var skip = request.query.skip; Report.find({}).limit(take).skip(skip).exec(function (err,reports) { callback(err,reports,response); }); } function _getReport (request,response,next) { var id = request.params.id; Report.findById({_id: id}, function (err,report) { callback(err,report); }); } function _createReport (request,response) { var newReport = new Report(); newReport.text = request.body.text; newReport.category = request.body.category; newReport.author = request.session.userId; newReport.save(function (err,savedReport) { callback(err,savedReport._id,response); }); } function _updateReport (request,response) { var id = request.params.id; var update = request.body.report; Report.findByIdAndUpdate(id, update, function (err,foundReport) { callback(err,foundReport,response); }); } function _deleteReport (request,response) { var id = request.params.id; Report.findByIdAndRemove(id, function (err,foundReport) { callback(err,foundReport,response); }); } function _getReports (request,response,next) { var take = request.query.take; var skip = request.query.skip; Report.find({}).limit(take).skip(skip).exec(function (err,reports){ callback(err,reports,response); }); } function _getCategories (request,response) { var take = request.query.take; var skip = request.query.skip; Report.find({}).limit(take).skip(skip).exec(function (err,reports) { callback(err,reports,response); }); } function _getCategoryReports (argument) { var _id = mongoose.Types.ObjectId(request.params.id); Report.find({category:id},{category:false},function (err, foundReports) { callback(err,foundReports,response); }); } function _createCategory (request,response) { var newCategory = new Category(); newCategory.name = request.body.name; newCategory.save(function (err,savedCategory) { callback(err,savedCategory._id,response); }); } function _updateCategory (request,response) { var id = request.params.id; var update = request.body.category; Category.findByIdAndUpdate(id, update, function (err,foundCategory) { callback(err,foundCategory,response); }); } function _deleteCategory (request,response) { var id = request.params.id; Category.findByIdAndRemove(id, function (err,foundCategory) { callback(err,foundCategory,response); }); } function callback (err,object,response) { if (err) response.status(500).send(JSON.stringify(err)); response.send(JSON.stringify(object)); } var apiController = { getReports: _getReports, getReport: _getReport, createReport: _createReport, updateReport: _updateReport, deleteReport: _deleteReport, getCategories: _getCategories, getCategoryReports: _getCategoryReports, createCategory: _createCategory, updateCategory: _updateCategory } return apiController; })(); 

在此之前,确保mongoose连接:

 var connectToMongoose = function (mongoose,app) { var connect = function () { var options = { server: { socketOptions: { keepAlive: 1 } } }; mongoose.connect( 'mongodb://localhost/data4', options); } mongoose.connection.on('connected', function () { console.log('Connected to db'); app.listen(32884, function() { console.log("Listening at \"data4 port\" @:32884"); }); }) mongoose.connection.on('error', function (err) { console.log(err); }); mongoose.connection.on('disconnected', function () { console.log('Disconnected from db, attempting to connect again...'); app.close(); connect(); }); connect(); }; module.exports = connectToMongoose; 

这是由require('./db/mongoose-connect.js')(mongoose,app);调用的require('./db/mongoose-connect.js')(mongoose,app);

我究竟做错了什么?

这里有几个问题,我抓住了蝙蝠。

首先,我没有看到将mongoose ODM显式连接到mongo服务器+数据库的mongoose.connect()行。 一个例子是:

 var mongoose = require( 'mongoose' ), Schema = mongo.Schema, ObjectId = mongo.Schema.ObjectId; mongoose.connect( 'mongodb://localhost/db_name' ); 

您的模式导出看起来很好。 但是你使用一个匿名函数作为你的导出。 既然你这样做,你的require声明需要改变一点:

 var Report = require('../models/Report')(); var Category = require('../models/Category')(); 

注意require语句末尾的() 。 您需要执行您定义的模型文件的module.export函数。

编辑:我看到你添加你的mongoose连接代码。 此时,执行您在模型文件中指定的module.exports函数应该允许您的mongoose模型按预期运行。

当你导出一个函数;

 // file: A.js module.exports = function () { //some logic }; 

而你想在另一个文件上使用它,当你需要A文件时,你正在导入一个函数,为了使用这个函数,你需要调用它。

 // file: B.js var A = require('./A.js'); A(); 

所以你的模型正在导出一个函数

 module.exports = (function() { var mongoose = require('mongoose'), Schema = mongoose.Schema, ObjectId = Schema.ObjectId; // .. // some code // .. return mongoose.model('Report', reportSchema); }); 

当你从你的控制器导入你的模型时,你需要执行你导入的函数,这样你的Reportvariables就包含了创build的模型:

     module.exports =(function(){

         var mongoose = require('mongoose');
         var Report = require('../ models / Report')();

我已经创build了一个如何使用模块而不使用IIFE编写代码的要点 。 https://gist.github.com/wilsonbalderrama/d5484f3f530899f101dc实际上,如果您下载文件夹中的所有文件并运行:

 $ sudo npm install $ mocha 

你可以看到为控制器创build的所有testing都通过了。


此外,您不需要在Node.JS中使用IIFE ,因为当您创build模块时,因为您已经在Node.JS中使用模块已经有一个隔离范围。

 // IIFE module.exports = (function() { var apiController = { getReport: function () {} } return apiController; })(); 

在Node.JS中,您可以导出一个对象,

 // GOOD WAY module.exports = { getReport: function () {} };