如何构建涉及大量地理位置计算的应用程序?

时间:2018-04-30 08:35:20

标签: c# mongodb redis azure-cosmosdb asp.net-core-webapi

我正在尝试从后端开始创建一个简单的社交网络应用。

应用说明

当用户打开应用时,将根据他/她的 地理位置,年龄和性别 显示用户列表。

一位用户被视为他不会再次出现。

技术

我使用Azure CosmosDB(MongoDB实现)和Azure Redis缓存来存储文档。

我处理问题的方法

我在cosmosdb中保存了所有用户数据库。我根据地理坐标和年龄及性别偏好过滤器查询用户ID,并将结果限制为5000.

我还应用了一个过滤器,如果用户已被查看过滤器。我正在维护集合,对于每个用户,他查看的所有用户ID都将保存为文档。

我第一次从cosmosdb获得5000个id,并将4950放在redis缓存中(有一个到期时间)。使用剩余的50个ID我将从cosmosdb获取用户并将其作为对api调用的响应返回。对于后续调用,我从redis缓存中获取下一个50个ID并获取这些用户并作为响应返回。

我正面临的问题

获取5000个用户是一个耗时的步骤,因为它涉及地理定位计算和其他过滤。我创建了一个示例用户数据库,其中有100万英里范围内的近200万用户,我应该根据我的偏好获得100,000个用户,即年龄和性别我没有应用5000限制。 这样做大约需要25秒。

应用5000限制将仅在最初运行查询1 - 1.5秒。在用户被观看时购买,即当 Not-In($ nin)过滤器将排除那些5000 ID时间最终会增加。从缓存中获取的时间很快,但是当缓存耗尽或过期并且我们必须访问cosmos db以查询5000个以上的用户时,由于他已经查看过的用户不断增加,所以需要更多时间。

统计

时间格式为小时:分钟:秒。 它仅针对性能统计执行。实际Api请求每次将提供50个用户(大部分时间来自缓存)。

第一次

获得5000场比赛的时间是00:00:01.22

设置Viewed Ids所需的时间是00:00:00.06

第二次

获得5000场比赛的时间是00:00:02.49

设置Viewed Ids所需的时间是00:00:00.67

: :

第十五次

获得5000场比赛的时间是00:00:23.05

设置Viewed Ids所需的时间是00:00:09.23

问题

如何改进架构以获得更好的性能? Uber,Tinder等涉及用户Geo-Location计算的应用程序如何构建其应用程序?有没有更好的方法来建模问题或建模数据?

任何帮助将不胜感激。谢谢。

2 个答案:

答案 0 :(得分:1)

200万用户就足以让您开始有一个好的索引策略来使数据库查询正常工作。地理查询提供了一个独特的索引问题,因为它们是对两个相关变量(即经度和纬度)的搜索。

很好地描述了Microsoft SQL服务器如何执行spacial index over here,这也很好地总结了索引问题。

虽然我没有亲自使用它,但CosmoDB似乎现在也有一些支持。请参阅thisthis

答案 1 :(得分:1)

我要做的第一件事就是稍微重新考虑一下你的期望 - 如果没有附近的比赛(或者即使如此),只需找到50或5000(或任何 n )最近的项目可能会涉及漫长的搜索但是如果你的数据库被正确编入索引,你可以在一个点的某个半径 r 内非常有效地搜索,然后按距离对这些结果进行排序。如果您有或期望拥有大量坐标,我建议您多次这样做,换句话说,搜索100米的所有匹配,按距离排序,然后如果您需要更多,请搜索500米内的所有匹配并排除你已经看过的那些,等等长达10公里或25公里,或者你的应用所要求的。

MongoDB有quite efficient index可用于地理空间坐标(基本上是划分为B +树的世界地图)。 The '$near' query允许您指定最小和最大距离,默认情况下按距离排序,因此对于这种基于距离的分层搜索非常方便。但是,您必须将坐标(在数据库和查询中)格式化为GeoJSON Point对象(如果它们尚未存在)。