如何对两个属性而不是 [ lng, lat ] 数组进行地理搜索?

Posted

技术标签:

【中文标题】如何对两个属性而不是 [ lng, lat ] 数组进行地理搜索?【英文标题】:How to do geo searches on two properties as opposed to an array of [ lng, lat ]? 【发布时间】:2014-06-22 21:13:08 【问题描述】:

Mongo 中地理搜索的所有示例和实现,我已经能够找到,使用数组属性 [lng, lat] 来执行搜索:

一个示例记录是:


   name: 'foo bar',
   locations: [
     
       name: 'franks house',
       geo: [-0.12, 34.51]
     ,
     
       name: 'jennifers house',
       geo: [-0.09, 32.17]
     
   ]

结果查询:

db.events.find( 'locations.geo':  $nearSphere: [ -0.12, 34.51 ], $maxDistance: 0.02 )

这很好用,但记录的格式不适合用户读取或写入,因为它不是自记录 latlng 在该数组中的位置。有陷阱的空间。我想让记录更人性化:


   name: 'foo bar',
   locations: [
     
       name: 'franks house',
       lat: 34.51,
       lng: -0.12
     ,
     
       name: 'jennifers house',
       lat: 32.17,
       lng: -0.09
     
   ]

对于这种类型的记录,生成的 mongo 查询会是什么样子?我还没有找到任何这样的例子,所以想知道这是否可能。

【问题讨论】:

如果您想使用您提供的 mongo 地理运算符来保持 [lon, lat] 格式。无论如何,只是一个旁注,通常“用户”不应该直接从数据库中读取/写入(MVC?)。 这是一个 REST API,我需要最简单的方法来返回 JSON 结果。它不需要与数据库结构完全一样,但是我必须做的数据格式越少,响应时间就越快。 【参考方案1】:

不建议对纬度和经度使用单独的字段。 2dsphere 索引用于索引需要坐标数组的地理空间数据,请参阅documentation。这就是您找不到单独坐标字段示例的原因。

您应该将表示与数据存储分开。仅仅因为坐标存储在数组中,您不一定需要将它们作为数组呈现给用户。例如,您可以在 save 上使用预调用将单独的参数存储在数组中,例如:

var schema = new Schema(..);
schema.pre('save', function (next) 
  this.coordinates = [this.longitude, this.latitude]
  next();
);

【讨论】:

是的,这是我的第二个选择,但我想先检查一下。您的回答几乎是全面的,但我使用这种方法遇到的一个问题是如何获取结果并轻松转换回用户友好的数据结构。我在 Mongoose 中找不到像 schema.post('find', ... 这样的东西。你能详细说明一下吗? 那么,无论何时进行查询并返回,对 doc 对象所做的任何修改都将应用于所有对象结果? 我不能肯定地说,但我认为是的。如果它不起作用,那么您可以改用toObject(),然后将其传递给JSON.stringify()。您可以在此处找到示例:mongoosejs.com/docs/api.html#document_Document-toObject

以上是关于如何对两个属性而不是 [ lng, lat ] 数组进行地理搜索?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 StandaloneSearchBox 获取 Lat 和 Lng?

我如何知道一个 Lat,Lng 点是不是包含在一个圆圈内?

错误:InvalidValueError:setCenter:不是LatLng或LatLngLiteral:在属性lat中:不是数字

如何将地理位置 lat lng 从函数传递到 React 中另一个函数的“ll”属性?

如果我有一个 lat/lng,我假设它是 0,0,那么我如何计算另一个 lat/lng 对的 x、y 坐标?

php计算两个经纬度之间的距离问题,求指导