这是我的控制器文件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
这是我正在使用的依赖项的版本:
答案 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非常正确我尝试了它并且必须说它对我来说效果很好