不能让我的地理空间查询工作.在Node中查询Mongo
Can't get my Geospatial Query to Work. Querying Mongo in Node
一旦用户登录他/或她的位置报告。并继续报告当前用户的位置每15分钟在那里。或者至少等到他们的疗程结束。使用Locate方法将用户位置读入数据库。它存储在与该特定用户关联的数据库中的位置数组中。这一切都很好。
将使用scan方法从数据库中读取用户位置。
我想知道如何创建一个2dsphere周围的位置坐标。我知道我得去目标地点。坐标,这样mongo就知道把它当作二维球体。我知道我必须使用User。ensureIndex({地点:" 2 dsphere "})。我的问题是:
1)应该是User.ensureIndex("location。坐标":2dsphere)或("location": 2dsphere)。这个会放在app.js.
的顶部吗?2)在我的扫描方法中,我试图为具有匹配的用户名的文档创建逻辑和查询,除了在300米内。最后我的问题是我最后一个结构化正确的Mongo查询
我的mongo Schema是这样的:
var userSchema = mongoose.Schema({
username: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true
},
email: {
type: String
},
location:
{
type: "Point",
coordinates: [Number, Number],
datetime: Date
},
points: {type:Number, default:10000},
imageUrl: {type:String, default:'/img/gravatar.jpg'}
});
我的app.js是这样设置的:
var User = require('../models/users.js');
var userController = {
locate: function (req, res) {
var data = req.body;
var date = new Date();
var username = req.user.username;
User.findOne({username:username}, function(err, user) {
if (err) return handleErr(err);
find = {
coordinates: [data.longitude, data.latitude],
datetime: date
};
user.location.push(find);
user.save();
});
},
scan: function (req, res) {
var date = new Date();
var twentyb4 = date.setMinutes(date.getMinutes - 15);
User.find({"datetime": {$gte: twentyb4}}, function (err, user) {
if (err) return handleErr(err);
for (var i = 0; i < user.length; i++) {
//return users other than current user
if(req.user.username !== user[i].username){
User.find({$and: [{username: user[i].username}, {$near: {$geometry: {type: "Point", coordinates: [ req.user.longitude, req.user.latiude ]}, $maxDistance: 300, $minDistance: 0}}]}, function(err, data){
if (err) return handleErr(err);
console.log(data.username);
});
}
}
});
};
所以scan函数最终要做的是找到数据库中不包括当前用户的所有用户。然后它只过滤那些在最近20分钟内登录过的用户。然后再进行一次筛选,比较其他用户最后报告的位置与当前用户的位置
你的模式是错误的,你需要修复这个:
location:
{
type: "Point",
coordinates: [Number, Number],
datetime: Date
},
:
location: {
"type": { "type": String, "default": "Point" },
"coordinates": [Number, Number],
"datetime": Date
},
由于"type"键工作被混淆,并且"Point"不是猫鼬数据类型。
您还需要为geoSpatial查询定义索引:
userSchema.index({ "location": "2dsphere" });
那么你的查询是相当简单的(你不需要$and
在这里,因为所有的查询参数都是一个"answers"条件),你真的想要 $nearSphere
这里与现实世界的坐标:
User.find({
"username": user[i].username,
"$nearSphere": {
"$geometry": {
"type": "Point",
"coordinates": [ parseFloat(req.user.longitude), parseFloat(req.user.latiude) ]
},
"$maxDistance": 300,
"$minDistance": 0
}
}, function(err, data) {
});
也要注意parseFloat
,因为我无法立即回忆起Mongoose是否真的有这样的$nearSphere
查询的"类型转换"。
我还建议这里"不要循环",并且一次获取除当前用户名之外的所有用户。简单,有一些预过滤和 $in
运算符:
// Filter out username values only except for the current user
var otherUsers = user.map(function(u) {
return u.username
}).filter(function(u) { return u != req.user.username });
if ( otherUsers.length > 0 ) {
User.find({
"username": { "$in": otherUsers },
"$nearSphere": {
"$geometry": {
"type": "Point",
"coordinates": [ parseFloat(req.user.longitude), parseFloat(req.user.latiude) ]
},
"$maxDistance": 300,
"$minDistance": 0
}
}, function(err, data) {
});
} else {
// no-one else is within the time :(
}
现在您在一个查询中测试了所有其他用户,因此您不需要为循环结果和相关的异步控制而烦恼,否则您也会真正需要这些。
您只需要创建一次索引(ensureIndex已弃用,createIndex中存在相同的功能)。由于您使用的是mongoose,所以只需在模式上定义索引,例如
userSchema.index({location: '2dsphere'});
你的查询差不多完成了,这是正确的版本。
var geoJSONpoint = {
type: 'Point',
coordinates: [
req.user.longitude,
req.user.latitude
]
}
User.find({ username: user[i].username, location: { $near: { $geometry: geoJSONpoint, $maxDistance: 300 } } })
...
下面是可行的解决方案:
我需要有:
var userSchema = mongoose.Schema({
username: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true
},
location:
{
type: { type: String, default: "Point" },
coordinates: [Number, Number],
datetime: Date
},
email: {
type: String
}
})
userSchema.index({ "location.coordinates": "2dsphere"}); //In my model
这是我在Node (server)中的控制器:
scan: function (req, res) {
var date = new Date();
var minusmin = date.setMinutes(date.getMinutes() - 20);
User.find({ "location.datetime": {$gte: minusmin}}, function (err, user) {
if (err) return handleErr(err);
for (var i = 0; i < user.length; i++) {
//return users other than current user
if(req.user.username !== user[i].username){
User.find({ username: user[i].username, "location.coordinates": { $nearSphere: { $geometry: { type: "Point", coordinates: [ req.user.location.coordinates[0], req.user.location.coordinates[1] ]}, $maxDistance: 300 } } }, function(err, data){
if (err) return handleErr(err);
console.log(data);
});
}
}
res.send(user);
});
}
- JSON:查询联接表不工作(Cordova Mobile)
- 无法使我的文本参数与我的查询一起工作
- 如何正确创建带有“Url.Action”的查询字符串的网址,以便它在Firefox中工作
- 媒体查询打印无法通过 javascript 命令工作
- 忽略服务工作进程请求中的查询参数
- j查询事件已记录.它究竟是如何工作的
- j查询下拉菜单.页面标记无法正常工作 - 或者我想要它的方式
- j查询每个函数无法正常工作
- AJAX 查询工作 50+ 次,然后崩溃 JavaScript
- j查询同位素错误.停止在 Wordpress 中工作
- 通过输入键(不起作用)或搜索按钮(工作)查询结果
- j查询验证规则无法正常工作
- j查询延迟无法正常工作
- 提前输入.js:页脚查询如何工作
- @media查询以奇怪的方式工作
- 用于将值从复选框传递到查询字符串的 JavaScript 无法正常工作
- j查询轮播/图库无法正常工作
- 如何在使用新列升级表模式时使SELECT查询工作
- 不能让我的地理空间查询工作.在Node中查询Mongo
- PHP脚本不返回查询,但MySql查询工作