我在Symfony2与Doctrine合作。
我有一个名为Landmarks
的实体数据库,其中每个实体都与MapMarker
实体有1:many
关系,而MapMarker
实体有一个latitude
和longitude
字段,例如"中央公园"可能是一个有许多"入口"的Landmark
,这些入口将存储为MapMarkers
。
然后,我有另一个名为Property
的实体,它与MapMarker
具有1:1
关系。
对于任何给定的Property
,在数据库中查找所有附近的Landmarks
的最佳方法是什么,按Landmark最近的MapMarker
排序?
在这个应用程序的遗留版本中,没有Doctrine或Symfony2,我是这样做的:
-
检索数据库中的所有
Landmarks
-
对于每个
Landmark
,在PHP函数中遍历其每个MapMarkers
,并计算property's MapMarker's lat,lng
和Landmarks MapMarker's lat,lng
之间的距离。 -
如果任何计算的距离小于或等于我选择的某个预先确定的常数(比如3km),那么我在
many:many
关系图中将Property
与Landmark
联系起来。 -
稍后,当在数据库中查询
Landmarks
附近的Property's
时,它将只经过链接的Landmarks
’MapMarkers
,然后再次计算最近的MapMarker
和距离,以进行如下显示:
您房产附近的地标:
- 中央公园,正门-2.4公里
- 等等
这样做的好处是,通过在Property
和Landmark
之间创建永久链接,我自动获得了附近Landmarks
的"短列表",用于计算昂贵的距离公式。
然而,正如您可能注意到的,当添加新的Landmark
或Landmark
的MapMarkers
发生更改时,会出现问题。此外,每次搜索Property
时计算距离仍然相当慢(或者如果通过Landmark
找到所有Properties
则相反)。
我真的希望能想出一个更好的方法,现在我正在迁移到Symfony2和Doctrine。
有什么想法吗?
好吧,Symfony2和Doctrine不会让你摆脱通常的数据库/PHP约束,所以这几乎是一个调整现有逻辑的问题。
话虽如此,但在我的脑海中,我可能会做一些类似的事情:
- Join使用纬度/经度的BETWEEN查询数据库(即:lat在marker_lat+X/marker_lat-X之间,long在marker_long+X/marker_long-X之间),以获得附近地图标记的短列表
- 编写一个函数来计算距离并保持最接近
如果你问我的话,不要用标记*X条创建一个全新的表,这会导致可扩展性较差,但显然这取决于你的应用程序限制,所以我真的无法为你考虑清楚。