Mongoose / MongoDb获取错误geoNear不是一个函数

时间:2018-01-04 15:08:24

标签: node.js mongodb mongoose

这是我的控制器文件locations.js

var mongoose = require('mongoose');
var Loc = mongoose.model('location');

module.exports.locationsListByDistance = function(req, res) {
  var lng = parseFloat(req.query.lng);
  var lat = parseFloat(req.query.lat);
  var point = {
    type: "Point",
    coordinates: [lng, lat]
  };
  var geoOptions = {
    spherical: true,
    maxDistance: 1000
  };

  Loc.geoNear(point, geoOptions, function (err, results, stats) {
    console.log(results);
  });
};

我的模型文件locations.js

var mongoose = require('mongoose');

var reviewSchema = new mongoose.Schema({
    author: String,
    rating: {
        type: Number,
        required: true,
        min: 0,
        max: 5
    },
    reviewText: String,
    createdOn: {
        type: Date,
        "default": Date.now
    }
});

var openingTimeSchema = new mongoose.Schema({
    days: {
        type: String,
        required: true
    },
    opening: String,
    closing: String,
    closed: {
        type: Boolean,
        required: true
    }
});

var locationSchema = new mongoose.Schema({
    name: {
        type: String,
        required: true
    },
    address: String,
    rating: {
        type: Number,
        "default": 0,
        min: 0,
        max: 5
    },
    facilities: [String],
    // Always store coordinates longitude, latitude order.
    coords: {
        type: [Number],
        index: '2dsphere'
    },
    openingTimes: [openingTimeSchema],
    reviews: [reviewSchema]
});

mongoose.model('location', locationSchema, 'locations');

每当我运行http://localhost:3000/api/locations?lng=-0.9690884&lat=51.455041时,我都会收到错误geoNear不是函数

  

TypeError:Loc.geoNear不是函数       在module.exports.locationsListByDistance(/home/shackers/Projects/mean/loc8r/app_api/controllers/locations.js:51:7)       在Layer.handle [as handle_request](/home/shackers/Projects/mean/loc8r/node_modules/express/lib/router/layer.js:95:5)       在下一个(/home/shackers/Projects/mean/loc8r/node_modules/express/lib/router/route.js:137:13)       在Route.dispatch(/home/shackers/Projects/mean/loc8r/node_modules/express/lib/router/route.js:112:3)       在Layer.handle [as handle_request](/home/shackers/Projects/mean/loc8r/node_modules/express/lib/router/layer.js:95:5)       at /home/shackers/Projects/mean/loc8r/node_modules/express/lib/router/index.js:281:22       在Function.process_params(/home/shackers/Projects/mean/loc8r/node_modules/express/lib/router/index.js:335:12)       在下一个(/home/shackers/Projects/mean/loc8r/node_modules/express/lib/router/index.js:275:10)       在Function.handle(/home/shackers/Projects/mean/loc8r/node_modules/express/lib/router/index.js:174:3)       在路由器(/home/shackers/Projects/mean/loc8r/node_modules/express/lib/router/index.js:47:12)       在Layer.handle [as handle_request](/home/shackers/Projects/mean/loc8r/node_modules/express/lib/router/layer.js:95:5)       在trim_prefix(/home/shackers/Projects/mean/loc8r/node_modules/express/lib/router/index.js:317:13)       at /home/shackers/Projects/mean/loc8r/node_modules/express/lib/router/index.js:284:7       在Function.process_params(/home/shackers/Projects/mean/loc8r/node_modules/express/lib/router/index.js:335:12)       在下一个(/home/shackers/Projects/mean/loc8r/node_modules/express/lib/router/index.js:275:10)       at /home/shackers/Projects/mean/loc8r/node_modules/express/lib/router/index.js:635:15

这是我正在使用的依赖项的版本:

  • 节点:8.9.3 npm:5.5.1 express:4.15.5 mongoose:5.0.0 mongoDb:3.6.1

9 个答案:

答案 0 :(得分:7)

router.get('/', () => {
    Loc.aggregate([
        {
            $geoNear: {
                near: 'Point',
                distanceField: "dist.calculated",
                maxDistance: 100000,
                spherical: true                
            }
        }
    ]).then(function(err, results, next){
        res.send();
    }).catch(next);
});

参考: - https://docs.mongodb.com/manual/reference/command/geoNear/

答案 1 :(得分:5)

发生此错误是因为曾经支持.geoNear,但不再支持使用Node MongoDB v3驱动程序的Mongoose 5。

此问题记录在Migrating to Mongoose 5文档中,该文档又链接到MongoDB 3 drive release notes,其中提供了有关建议替换的声明:

  

geoNear命令的功能在语言的其他地方,未加密的集合上的$ near / $ nearSphere查询运算符以及所有集合的$ geoNear聚合阶段中都是重复的。

实际上,官方文档赞同使用其他答案中记录的$geoNear

答案 2 :(得分:2)

我遇到了完全相同的问题而且我已经放弃了以前使用的方法(看起来你也有这种方法)。以下是一个不会抛出错误的替代方法,并且应该给出与使用Loc.geoNear之后相同的结果:

Loc.aggregate(
        [
            {
                '$geoNear': {
                    'near': point,
                    'spherical': true,
                    'distanceField': 'dist',
                    'maxDistance': 1000
                }
            }
        ],
        function(err, results) {
            // do what you want with the results here
        }
    )

答案 3 :(得分:1)

我找到了解决方案。只需降级mongoose并安装4.9.1版本。最新版本的mongoose不支持Loc.geoNear

npm remove mongoose
npm install mongoose@4.9.1

答案 4 :(得分:0)

我认为你正在寻找这个,如果那里有错误,请纠正我。

module.exports.locationsListBydistance = function (req, res) {
    var lng = parseFloat(req.query.lng);
    var lat = parseFloat(req.query.lat);
    Loc.aggregate(
        [{
            $geoNear: {
                'near': {'type':'Point', 'coordinates':[lng, lat]},
                'spherical': true,
                'maxdistance': theEarth.getRadsFromDistance(20),
                'num':10,
                'distanceField': 'dist' 
            }
        }
        ], function(err, results) {
            var locations = [];
            console.log(results);
            results.forEach(function (doc) {
                locations.push({
                    distance: theEarth.getDistanceFromRads(doc.dist),
                    name: doc.name,
                    address: doc.address,
                    facilities: doc.facilities,
                    rating: doc.rating,
                    _id: doc._id
                });
            });
            sendJsonResponse(res, 200, locations);
        });
};

答案 5 :(得分:0)

router.get('/',function(req,res,next){
    Loc.aggregate([
        {
            $geoNear: {
                near: {type:'Point', coordinates:[parseFloat(req.query.lng), parseFloat(req.query.lat)]},
                distanceField: "dist.calculated",
                maxDistance: 1000,
                spherical: true                
            }
        }
    ]).then(function(Locs){
        res.send(Locs)
    })
})

答案 6 :(得分:0)

比Grider课程中的前两个答案更直接的IMO是:

  index(req, res, next) {
    const { lng, lat } = req.query;
    Driver.find({
      'geometry.coordinates': {
        $nearSphere: {
          $geometry: {
            type: 'Point',
            coordinates:[parseFloat(lng), parseFloat(lat)]
          },
          $maxDistance: 200000,
        },
      }
    })
    .then(drivers => res.send(drivers))
    .catch(next);
  }

这是本着他给出的原始定义的精神,并使用了与旧的geoNear相同的新功能,但现在它们已分离出球形和非球形版本。您需要:

    beforeEach((done) => {
  const { drivers } = mongoose.connection.collections;
  drivers.drop()
    .then(() => drivers.createIndex({ 'geometry.coordinates': '2dsphere' }))
    .then(() => done())
    .catch(() => done());
};

在前面提到的测试助手中。

答案 7 :(得分:-1)

 index(req, res, next) 
{
   const { lng, lat } = req.query;
   Driver.aggregate([
   {
     '$geoNear': {
                    "near": { 'type': 'Point', 
                    'coordinates': [parseFloat(lng), parseFloat(lat)] },
                    "spherical": true, 
                    "distanceField": 'dist', 
                    "maxDistance": 200000
                }
            }
        ])
            .then(drivers => res.send(drivers))
            .catch(next);
    }

答案 8 :(得分:-2)

用户给出的答案:phao5814非常正确我尝试了它并且必须说它对我来说效果很好