有关在Azure存储中存储和搜索地理位置数据的问题

有关在Azure存储中存储和搜索地理位置数据的问题,azure,geolocation,Azure,Geolocation,大家好,我正在建立一个网站,需要有能力存储一个人的物理位置,并允许有人在该位置的半径范围内搜索其他人。举个例子,让我们假设它是一个约会网站(它不是),因此作为一个用户,您希望找到距离您当前位置50英里以内的符合其他搜索条件的人 目前我正在Azure表存储中存储所有用户信息。然而,这是我第一次尝试创建一个地理感知搜索算法,所以我想验证我不会浪费时间做一些完全疯狂的事情。为此,我的实施思路如下: 在Azure表中存储用户位置的经度和纬度 每个条目的PartitionKey是该人居住的州(或美国以外的

大家好,我正在建立一个网站,需要有能力存储一个人的物理位置,并允许有人在该位置的半径范围内搜索其他人。举个例子,让我们假设它是一个约会网站(它不是),因此作为一个用户,您希望找到距离您当前位置50英里以内的符合其他搜索条件的人

目前我正在Azure表存储中存储所有用户信息。然而,这是我第一次尝试创建一个地理感知搜索算法,所以我想验证我不会浪费时间做一些完全疯狂的事情。为此,我的实施思路如下:

  • 在Azure表中存储用户位置的经度和纬度
  • 每个条目的PartitionKey是该人居住的州(或美国以外的国家)
  • 我想用哈弗森方程计算当前用户和所有其他用户之间的距离。我假设我可以将它嵌入到我的LINQ查询中
  • 最终,我希望能够得到半径范围内所有州/国家的列表,以便根据PartitionKey进行优化
  • 当然,这一实施策略会带来一些问题:

  • 如果我在LINQ查询中执行哈弗森方程,它在哪里执行?我最不希望的是我的WebRole从azure存储中提取每条记录,以便在应用程序进程中对其运行此haversine等式
  • 使用Azure存储执行此操作的想法完全疯狂吗?我知道有像MongoDB这样的解决方案能够内置空间搜索查询。我喜欢Azure的可伸缩性,但是否有更好的替代方案值得我研究

  • 提前谢谢你的帮助

    如果您希望对Azure表进行快速查询,则查询必须针对分区键和行键运行。另外,如果您使用LINQ查询Azure表,那么您需要小心使用哪些函数。如果可以对所有行计算一次该值,那么LINQ将非常聪明,并在将查询发送到AZT之前对其进行评估,但是如果需要对每一行进行评估,那么您只能使用Azure支持的值(这是一个很短的列表)

    如果希望为区域使用边界正方形而不是边界圆,则可以实现此功能。将纬度存储在
    PartitionKey
    中,将经度存储在
    RowKey
    中,并进行如下查询:

    var query = from UserLocation ul
                in repository.All()
            where
                ul.PartitionKey.CompareTo(minimumLatitude) > 0
                && ul.PartitionKey.CompareTo(maximumLatitude) < 0
                && ul.RowKey.CompareTo(minimumLongitude) > 0
                && ul.RowKey.CompareTo(maximumLongitude) < 0
            select
                ul;
    
    var query=来自用户位置ul
    在repository.All()中
    哪里
    ul.分区键比较(最小纬度)>0
    &&ul.分区键比较(最大纬度)<0
    &&ul.RowKey.CompareTo(最小经度)>0
    &&ul.RowKey.CompareTo(最大经度)<0
    选择
    ul;
    

    不过,这可能不像你希望的那么聪明。如果这对你不起作用,那么你需要考虑其他的选择。如果您希望留在Microsoft系列中,SQL Azure将提供支持。

    如果您希望对Azure表进行快速查询,则查询必须针对分区键和行键运行。另外,如果您使用LINQ查询Azure表,那么您需要小心使用哪些函数。如果可以对所有行计算一次该值,那么LINQ将非常聪明,并在将查询发送到AZT之前对其进行评估,但是如果需要对每一行进行评估,那么您只能使用Azure支持的值(这是一个很短的列表)

    如果希望为区域使用边界正方形而不是边界圆,则可以实现此功能。将纬度存储在
    PartitionKey
    中,将经度存储在
    RowKey
    中,并进行如下查询:

    var query = from UserLocation ul
                in repository.All()
            where
                ul.PartitionKey.CompareTo(minimumLatitude) > 0
                && ul.PartitionKey.CompareTo(maximumLatitude) < 0
                && ul.RowKey.CompareTo(minimumLongitude) > 0
                && ul.RowKey.CompareTo(maximumLongitude) < 0
            select
                ul;
    
    var query=来自用户位置ul
    在repository.All()中
    哪里
    ul.分区键比较(最小纬度)>0
    &&ul.分区键比较(最大纬度)<0
    &&ul.RowKey.CompareTo(最小经度)>0
    &&ul.RowKey.CompareTo(最大经度)<0
    选择
    ul;
    

    不过,这可能不像你希望的那么聪明。如果这对你不起作用,那么你需要考虑其他的选择。如果您想留在Microsoft系列中,SQL Azure支持。

    在SQL Azure中使用空间查询(大约500万条记录)后,我可以确认它可以非常快-很值得您一看。

    在SQL Azure中使用空间查询(大约500万条记录)我可以确认,它可以非常快-可能值得您一看。

    存储latitude不是因为分区键创建了太多分区吗?如果您想进行时空查询,例如。,获取eifel tower X米范围内和指定日期时间范围内的所有数据?在优化读取时,不要担心创建太多分区,它们不是宝贵的资源,您也不会为此收取费用。创建所需数量。使用表存储,您可以获得2个参数,您可以在其中运行一个范围,并在您有空间存储的情况下创建尽可能多的精确匹配。所以,如果你有一个固定的日期范围,比如一天,你可以有PK=yyyyMMdd |经度RK=latitude。在这一点上你真的在扩展东西,我想你会想要比这更大的灵活性。将纬度存储为分区键不会创建太多分区吗?如果你想进行时空查询,例如。,获取eifel tower X米范围内和指定日期时间范围内的所有数据?在优化读取时,不要担心创建太多分区,它们不是宝贵的资源,您也不会为此收取费用。根据需要创建任意数量的参数。使用表存储可以获得2个参数