3

先介绍一下背景知识:GeoModel是我编写的一个库,它为 App Engine 应用程序添加了非常基本的地理空间索引和查询功能。它与地理散列的方法相似。GeoModel 中的等效位置哈希称为“geocell”。

目前,GeoModel 库为每个位置感知实体添加了 13 个属性 (location_geocell__n_, n =1..13)。例如,实体可以具有以下属性值:

location_geocell_1 = 'a'
location_geocell_2 = 'a3'
location_geocell_3 = 'a3f'
...

这是必需的,以便在空间查询期间不使用不等式过滤器。

13 属性方法的问题在于,对于应用程序想要运行的任何地理查询,必须定义和构建 13 个新索引。这绝对是一个维护麻烦,因为我刚刚在为项目重写演示应用程序时痛苦地意识到。这引出了我的第一个问题:

问题 1:每个索引是否有任何显着的存储开销?即,如果我有 13 个索引,每个索引有 n 个实体,而 1 个索引有 13n 个实体,那么前者在存储方面是否比后者差得多?

根据这篇文章,似乎 (1) 的答案是否定的,但我只是想看看是否有人有不同的经历。

现在,我正在考虑调整 GeoModel 库,以便只有一个名为 location_geocells 的 StringListProperty 而不是 13 个字符串属性,即:

location_geocells = ['a', 'a3', 'a3f']

这导致更清洁index.yaml。但是,我确实质疑性能影响:

QUESTION 2:如果我从 13 个字符串属性切换到 1 个 StringListProperty,查询性能是否会受到不利影响;我当前的过滤器看起来像:

query.filter('location_geocell_%d =' % len(search_cell), search_cell)

新的过滤器看起来像:

query.filter('location_geocells =', search_cell)

请注意,第一个查询具有 _n_ 个实体的搜索空间,而第二个查询具有 _13n_ 个实体的搜索空间。

似乎 (2) 的答案是,根据这篇博文中的提示 #6,两者都会产生相同的查询性能,但我想再次看看是否有人对此有任何不同的实际经验。

最后,如果有人有任何其他建议或技巧可以帮助提高存储利用率、查询性能和/或易用性(特别是 wrt index.yaml),请告诉我!源代码可以在这里找到geomodel & geomodel.py

4

3 回答 3

5

您是正确的,每个索引没有显着的开销 - 一个索引中的 13n 个条目或多或少等同于 13 个索引中的 n 个条目。但是,总索引计数限制为 100,因此这会占用相当多的可用索引。

也就是说,从可用性和索引消耗的角度来看,使用 ListProperty 绝对是一种优越得多的方法。如您所料,查询小索引和大得多的索引之间没有性能差异,假设两个查询返回相同的行数。

我能想到的使用单独属性的唯一原因是,如果您知道您只需要在某些详细级别上建立索引 - 但可以通过在插入时指定要添加到列表中的详细级别来更好地完成第一名。

请注意,在任何一种情况下,如果您打算结合排序顺序或不等式过滤器查询 geocell 属性,则只需要索引,但在所有其他情况下,自动索引就足够了。

于 2009-08-03T12:40:46.033 回答
1

最后,如果有人有任何其他可以帮助提高存储利用率、查询性能和/或易用性的建议或提示

出于上述原因,StringList 属性是一种可行的方法,但在实际使用中,可能希望将地理单元添加到自己先前存在的 StringList 中,以便可以查询多个属性。

因此,如果您要提供较低级别的 api,它可以与bill katz等全文搜索实现一起使用

def point2StringList(Point, stub="blah"):
    .....
    return ["blah_1:a", "blah_2":"a3", "blah_3":"a3f" ....]

def boundingbox2Wheresnippet(Box, stringlist="words", stub="blah"):
    .....
    return "words='%s_3:a3f' AND words='%s_3:b4g' ..." %(stub)

etc.
于 2009-08-03T15:47:37.923 回答
0

看起来你最终得到了 13 个索引,因为你用十六进制编码(为了人类可读性/地图级别?)。如果您充分利用了一个字节(ByteString)的全部潜力,那么每个字符(字节)将有 256 个单元而不是 16 个单元。通过将相同精度的索引数量减少到更少。

ByteString只是 str 的子类,如果长度小于 500 字节,则类似地进行索引。

但是级别的数量可能会更少;对我来说,对于“地球”上的大多数情况,4 或 5 个级别实际上已经足够了。对于较大的行星或在对每个沙粒进行编目时,无论使用何种编码,都可能需要引入更多的划分。在任何一种情况下,ByteString 都比十六进制编码好。并有助于大幅减少索引。

  • 为了表示 40 亿个低(est)级别的单元,我们只需要 4 个字节或仅4 个索引。(来自基本的计算机拱门或内存寻址)。
  • 为了表示相同,我们需要16 个十六进制数字或16 个索引

我可能是错的。可能是与地图缩放级别匹配的索引级别的数量更重要。请纠正我。如果这里只有一个(其他)人觉得这很有意义,我打算试试这个而不是十六进制:)

或者当我们沿着层次结构向下移动时,具有较少大单元 (16) 但更多 (128,256) 的解决方案。有什么想法吗?

例如:

  • [0-15][0-31][0-63][0-127][0-255] 给出 1G 低级单元,具有 5 个索引,log2 大小递减。
  • [0-15][0-63][0-255][0-255][0-255] 给出具有 5 个索引的 16G 低级小区。
于 2011-09-20T10:50:15.140 回答