Mongoose 按半径查找地理点

Mic*_*ski 3 mongoose node.js

我尝试通过半径找到地理点,我发现教程解释了如何做到这一点。

教程片段:

首先,我们需要创建一个模式。文档为我们提供了一些关于如何存储地理空间数据的示例。我们将在示例中使用旧格式。建议将经度和纬度存储在数组中。文档警告使用值的顺序,经度在前。

var LocationSchema = new Schema({  
  name: String,
  loc: {
  type: [Number],  // [<longitude>, <latitude>]
  index: '2d'      // create the geospatial index
 }
});
Run Code Online (Sandbox Code Playgroud)

首先,您可以在控制器中创建一个方法,它看起来像这样:

findLocation: function(req, res, next) {  
    var limit = req.query.limit || 10;

    // get the max distance or set it to 8 kilometers
    var maxDistance = req.query.distance || 8;

    // we need to convert the distance to radians
    // the raduis of Earth is approximately 6371 kilometers
    maxDistance /= 6371;

    // get coordinates [ <longitude> , <latitude> ]
    var coords = [];
    coords[0] = req.query.longitude;
    coords[1] = req.query.latitude;

    // find a location
    Location.find({
      loc: {
        $near: coords,
        $maxDistance: maxDistance
      }
    }).limit(limit).exec(function(err, locations) {
      if (err) {
        return res.json(500, err);
      }

      res.json(200, locations);
    });
}
Run Code Online (Sandbox Code Playgroud)

参考教程: How to use Geospatial Indexing in MongoDB with Express and Mongoose

从教程到我的项目实施源代码后,我没有从数据库中按半径接收正确的点(点不在半径内)。

我的问题是如何按半径接收地理点(公里或米无关紧要)?

谢谢,迈克尔。

小智 5

我之前在自己的数据库中处理过类似的问题。四处挖掘并找到答案很棘手,所以我将在这里分享。Mongoose 的 DB 包的地理空间元素没有很好的文档记录。

.find查询中,您需要使用比上面更复杂的对象。我发现以下构造工程,其中 maxDistance 以米为单位,坐标是 [经度,纬度] 的数组。

Location.find({
    loc: {
        $near: {
            $geometry: {
                type: "Point",
                coordinates: coords
            },
            $maxDistance: maxDistance
        }
    } 
}).then((err, locations) => {
    // do what you want here
})
Run Code Online (Sandbox Code Playgroud)

这消除了处理地球周长和所有这些混乱的需要。现在,这种查询风格在 Mongoose 中是原生的。我发现下面的函数有助于快速进行这些查询,因此您不必每次都处理尽可能多的格式。

var locQuery = (coords, distance) => {
    return { loc: { $near: { $geometry: { type: "Point", coordinates: coords }, $maxDistance: parseInt(distance)}}}
}
Run Code Online (Sandbox Code Playgroud)