我有一个数据集,目前只存储在一个JSON文件中,其中包含大约40k个不同的地理位置。它看起来像这样:
[
{"title": "Place 1", "loc": {"x": "00.000", "y": "00.00000"}},
{"title": "Place 2", "loc": {"x": "00.000", "y": "00.00000"}},
]
地方的loc
就是它的坐标。
我希望能够对这些数据运行查询,因此,对于任何给定的用户输入的loc
,我都可以获得n
最近的地方。
或者换句话说,我想写一些函数f
,这样就可以了:
def f(loc, n): ...
f({"x": "5", "y": "5"}, 3) #=> [{"title": "Place 1", "distance": 7.073}, {"title": "Place 2": "distance": 7.073}, {"title": "Place 3", "distance": 7.073}]
如果地点1,2和3都在{x: 0, y: 0}
。
我不知道解决这类问题的标准方法是什么。使用带有预计算距离索引的SQL DB不起作用,因为提供的loc
是任意的。遍历整个数据库并计算所有内容的距离效率太低,而且速度太慢。 (我需要< 30ms响应时间。)
唯一有意义的解决方案是以某种方式制作关闭位置的“桶”(在彼此的某些r
内),然后计算机用户给定的loc和桶的loc之间的距离缩小首先是选项。但我觉得创建这样一个解决方案本身就类似于根本不使用数据库;必须有一个更有效/行业标准的方法。有吗?
答案 0 :(得分:0)
这是nearest neighbor问题的一般形式(更正式地称为k-nearest neighbor)。你没错,solution that makes sense使用存储桶。您可以将存储桶存储在允许您利用SQL的数据库中,只过滤掉不在相应存储桶中的所有点。 Depending on your database,这实际上可能已经为您实施,这将是您建议的“行业标准”方法。
否则,自己编写它是非常有效的,可以在不偏离数据库的情况下完成。
答案 1 :(得分:0)
您可以使用具有点数据类型和MySQL等空间索引的数据库。您也可以使用四核或四叉树。它将平面细分并减小尺寸。你可以下载我的PHP类Hilbert-curve @ phpclasses.org。它使用四核,可以帮助组织桶中的位置并构建邻近搜索。由于特殊的数据库,四元组可以减少重叠搜索。
答案 2 :(得分:0)
Oracle提供Spatial数据功能。它有一个内置的最近邻函数SDO_NN,它将为你完成这项工作。只有无意中听到将把所有数据都放在db中,其余的将由oracle db来处理。