数字types错误与mongoose模型?

有500内部服务器错误,对于Error: TypeError: path must be a string

浏览器控制台指向ItemCtrl.js:35

 console.log('Error: ' + data); 

该错误的堆栈跟踪如下所示:

TypeError:path必须是位于Function.where(/ Users / Name / Downloads / dev)的Query.where(/Users/Name/Downloads/dev/v16/node_modules/mongoose/lib/query.js:593:11) /v16/node_modules/mongoose/lib/model.js:1040:18)。 (/Users/Name/Downloads/dev/v16/app/models/item.js:44:35)…

看来这个错误是从/app/models/item.js中的一行中得到的,特别是在else if语句中。因为else if注释掉了, else if这两个都是可用的。

 // load mongoose since we need it to define a schema and model var mongoose = require('mongoose'); var ItemSchema = mongoose.Schema({ title : String, position: Number }); // before validation starts, the number of Items is counted..afterwards, the position is set ItemSchema.pre("validate", function(next) { var doc = this; // if 'position' is not filled in, fill it in // not using !position because 0 might be a valid value if(typeof doc.position !== "number") { // count the number of Items * // use mongoose.model to fetch the model because it is not compiled yet mongoose.model("Item").count(function(err, num) { // if there was an error, pass it to next() if(err) return next(err); // set the position, then call next(); doc.position = num; return next(); }); } else if(typeof doc.position == "number") { console.log('yes, a number'); // check if there is an existing document with the same position // use mongoose.model to fetch the model because the model is not compiled yet mongoose.model("Item").where({_id: {$ne: doc._id}, position: doc.position}).count( function (err, count) { // if there was an error, pass it to next() if(err) return next(err); // if there is a doc with the SAME position, execute an update to MOVE DOWN all the $gte docs if(count > 0) { // use mongoose.model to fetch the model because the model is not compiled yet mongoose.model("Item").update({position: {$gte: doc.position}}, {position: {$inc: 1}}, {multi: 1}, function(err, numAffected) { console.log(numAffected); // Call next() (with or without an error) next(err); }); } else { // there are no docs that need to move down, so call next() next(); } }); } else { // there is no need to count or update positions, so call next() next(); } }); module.exports = mongoose.model('Item', ItemSchema); 
  • 数据的path是这样的:
  • 表单字段在/public/views/CreateItem.html
  • 到/public/js/controllers/ItemCtrl.js
  • 到/public/js/services/ItemService.js
  • 到/app/routes.js
  • 到/app/models/item.js
  • 数据可以在json的localhost:8080 / api / items中查看

/public/views/CreateItem.html

 <form> <div class="form-group"> <!-- BIND THESE VALUES TO formData.value IN ANGULAR --> <input type="text" class="form-control input-lg text-center" placeholder="Item" ng-model="formData.title"> <input type="number" class="form-control input-lg text-center" placeholder="0" ng-model="formData.position"> </div> <!-- createItem() WILL CREATE THE NEW ITEM VIA ANGULAR THROUGH NODE API TO MONGOOSE --> <button type="submit" class="btn btn-primary btn-lg" ng-click="createItem()">Add Item</button> </form> 

/public/js/controllers/ItemCtrl.js

 angular.module('ItemCtrl', []) // inject the Item service.factory into our controller .controller('ItemController', function($scope, $http, Items, isEmptyObjectFilter) { $scope.formData = {}; // CREATE ================================================================== // when submitting the add form, send the text to the node API $scope.createItem = function() { // validate the formData (using our exentions.js .filter) to make sure that something is there..if form is empty, nothing will happen if (!isEmptyObjectFilter($scope.formData)) { // call the create function from our service (returns a promise object) Items.create($scope.formData) // if successful creation, call our get function to get all the new items .success(function(data) { $scope.formData = {}; // clear the form so our user is ready to enter another $scope.items = data; // assign our new list of items }) .error(function(data) { console.log('Error: ' + data); }); } }; }); 

/public/js/services/ItemService.js

 angular.module('ItemService', []) // super simple service // each function returns a promise object .factory('Items', function($http) { return { get : function() { return $http.get('/api/items'); }, create : function(itemData) { return $http.post('/api/items', itemData); } } }); 

/app/routes.js

 // load the item model var Item = require('./models/item'); // expose the routes to our app with module.exports module.exports = function(app) { // create item and send back all items after creation app.post('/api/items', function(req, res) { console.log(req.body.position); // create an item, information comes from AJAX request from Angular Item.create({ title : req.body.title, position : req.body.position }, function(err, item) { if (err) res.send(err); // get and return all the items after you create another Item.find(function(err, items) { if (err) res.send(err) res.json(items); }); }); }); }; 

这里的问题是,mongooseAPI实际上并不使用你正在尝试的方式。

Model.where的mongoose v3.8.8文档显示,你可以使用ActiveRecord风格的方式,使用标准方法(比如gte )来链接属性名称(比如'age' )来形成一个查询:

 User.find({age: {$gte: 21}, callback) 

相当于

 User.where('age').gte(21).exec(callback) 

你的代码使用Model#find的散列条件风格,而不是其中的链式方法风格。

这是应该重写的行:

mongoose.model("Item").where({_id: {$ne: doc._id}, position: doc.position}).count( function (err, count) {

最简单的做法是在最后删除.count ,然后将.where更改为.count ,因为mongoose的Model#count会像这里一样使用条件散列。 代码应该像这样工作:

mongoose.model("Item").count({_id: {$ne: doc._id}, position: doc.position}, function (err, count) {

如果你想使用.where语法,你需要这样做:

mongoose.model("Item").where('_id').ne(doc._id).where('position').equals(doc.position).count( function(err, count)