结合geoNear查询和另一个查询值 [英] combine geoNear query with another query for a value

查看:317
本文介绍了结合geoNear查询和另一个查询值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用于使用node.js mongodb和mongoose实现的地理数据的api. 我想用两个条件查询我的数据.

I have an api for geo data realised with node.js mongodb and mongoose. I want to query my data with two criteria.

首先,我使用geoNear获取给定半径内的所有位置,效果很好. 其次,我想进一步根据位置类型过滤位置.

First i use geoNear to get all locations in a given radius which works fine. Second i want to filter the locations further by its type.

这是我的模式:

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" });

这是我的geoNear查询:

and this is my geoNear query:

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);
        });
    });

是否可以将geoNear查询与针对特定位置类型的查询结合使用?还是可以通过某种方式过滤结果?

Is it somehow possible to combine the geoNear query with a query for a specific type of location or can i filter the result somehow?

谢谢.

推荐答案

只要您的MongoDB服务器足够新,即2.6或更高版本,则此功能实际上已移至常规查询引擎.这里的mongoose方法包装了.runCommand()形式,该形式在所有将来的发行版中都已弃用,因此只需在标准查询中添加其他运算符即可.

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
});

$nearSphere 或其他用于选项的运算符.主要区别在于$maxDistance是使用GeoJSON表单时的米数,而不是弧度.

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.

当然也有 $geoNear > 聚合管道的运算符.从MongoDB 2.4开始,此功能可用,并且可以采用其他选项(例如查询")来进一步缩小结果范围.另一个可能的优点是,它将字段"字段投影到您的结果中,表示与查询点的距离".可以将其用于其他计算或自定义排序:

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
    }
);

要注意的其他区别是,在标准查询表单中,结果不再限于命令"表单中的100个文档.默认情况下,聚集$geoNear最多将100个文档作为结果,但是可以使用管道命令的附加限制"选项来调整返回的文档数.除了有最大条件的搜索结果以外,聚集语句不会对结果进行排序",从给定条件返回的结果是搜索结果中排名最高的结果,但是它们不会按顺序返回,因此您需要如图所示对它们进行排序.

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是否将其方法保留为这些形式之一的包装器"尚不清楚,但多数情况下不太可能,因此最好坚持使用受支持的形式.

In either case you should be moving your code to use either of these forms as the command form is considered deprecated and will be removed in the future. Whether the mongoose API retains it's method as a "wrapper" for one of these forms is unknown, but mostly unlikely, so it is better to stick with the supported forms.

这篇关于结合geoNear查询和另一个查询值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆