ark*_*hon 2 geospatial mongoose mongodb node.js aggregation-framework
我有一个用 node.js mongodb 和 mongoose 实现的地理数据api。我想用两个条件查询我的数据。
首先,我使用 geoNear 来获取给定半径内的所有位置,这很好用。其次,我想按其类型进一步过滤位置。
这是我的架构:
var GeoLocationSchema = new Schema({
name: String,
type: String,
loc: {
type: {
type: String,
required: true,
enum: ["Point", "LineString", "Polygon"],
default: "Point"
},
coordinates: [Number]
}
});
// ensure the geo location uses 2dsphere
GeoLocationSchema.index({ loc : "2dsphere" });
Run Code Online (Sandbox Code Playgroud)
这是我的 geoNear 查询:
router.route("/locations/near/:lng/:lat/:type/:max")
// get locations near the get params
.get(function(req, res) {
// setup geoJson for query
var geoJson = {};
geoJson.type = "Point";
geoJson.coordinates = [parseFloat(req.params.lng), parseFloat(req.params.lat)];
// setup options for query
var options = {};
options.spherical = true;
options.maxDistance = parseInt(req.params.max)/6370000;
// query db with mongoose geoNear wrapper
GeoLocation.geoNear(geoJson, options, function (err, results, stats) {
if (err)
res.send(err);
res.json(results);
});
});
Run Code Online (Sandbox Code Playgroud)
是否有可能将 geoNear 查询与特定类型位置的查询结合起来,或者我可以以某种方式过滤结果?
提前致谢。
As long as your MongoDB server is recent enough, being a version of 2.6 or greater then this functionality has actually been moved to the general query engine. The mongoose method here wraps the .runCommand() form which is considered deprecated for all future releases, so it is just a matter of placing a standard query with additional operators.
GeoLocation.find({
"$nearSphere": {
"$geometry": {
"type": "Point",
"coordinates": [parseFloat(req.params.lng), parseFloat(req.params.lat)]
},
"$maxDistance": distanceInMeters
},
"loc.type": "Point"
},function(err,docs) {
// The documents are also mongoose document objects as well
});
Run Code Online (Sandbox Code Playgroud)
See further options on $nearSphere or other operators for options. The main difference here is $maxDistance is in meters when a GeoJSON form is used, rather than radians where otherwise.
There is of course also the $geoNear operator for the aggregation pipeline. This is available as of MongoDB 2.4 and can take other options such as a "query" to narrow results further. The other possible advantage here is that it will "project" a field into your results representing the "distance" from the query point. This can be used in other calculations or custom sorting:
GeoLocation.aggregate(
[
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [parseFloat(req.params.lng), parseFloat(req.params.lat)]
},
"distanceField": "distance",
"maxDistance": distanceInMeters,
"spherical": true,
"query": { "loc.type": "Point" }
}},
{ "$sort": { "distance": -1 } } // Sort nearest first
],
function(err,docs) {
// These are not mongoose documents, but you can always cast them
}
);
Run Code Online (Sandbox Code Playgroud)
Other differences to note are that in the standard query form the results are no longer limited to 100 documents as they are in the "command" form. The aggregation $geoNear limits to 100 documents as results by default, but the number of documents returned can be tuned with an additional "limit" option to the pipeline command. The aggregate statement does not "sort" the results other than from the maximum documents to return from the search are the top results given the conditions, but they are not returned in order, so you would need to sort them as shown.
在任何一种情况下,您都应该移动代码以使用这两种形式中的任何一种,因为命令形式被认为已弃用并且将来会被删除。猫鼬 API 是否将其方法保留为这些形式之一的“包装器”尚不清楚,但几乎不可能,因此最好坚持使用受支持的形式。
| 归档时间: |
|
| 查看次数: |
4249 次 |
| 最近记录: |