如何使用关系查询地理空间查询/像后端系统这样的Tinder

时间:2014-10-09 03:08:40

标签: performance postgresql architecture scalability geospatial

我有一个应用程序,我根据用户的位置,上次活动和其他一些过滤器搜索用户,现在已经达到了性能不够好但必须由于用户数量增加而需要改进的程度。但是,我不确定前进的最佳方式是什么,并希望得到任何意见!

我的基本设置是两个表,让我们称之为用户和关系。每个用户都有许多属性,例如location,last_activity和各种属性。每个用户都可以与另一个用户(朋友/敌人)建立关系。

我想要做的查询(这很重要)是搜索附近的用户,这些用户履行了许多与用户尚未关联的属性。然后,用户将遍历列表并向列表中的每个用户添加关系。完成后查询另一个列表并重复。

目前它已在PostgreSQL中使用PostGIS实现地理索引,但它不具备可扩展性。

伪psql:

CREATE TABLE users
(
  id serial NOT NULL,
  location geometry,
  last_active timestamp NOT NULL,
  property1 int NOT NULL
)

CREATE TABLE relations
(
  user_id int NOT NULL,
  other_user_id int NOT NULL,
  relation_type char(1) NOT NULL
)

和查询

nearby := SELECT * FROM users 
    WHERE property1 > 1
    ORDER BY location <-> 'my location'::geometry
    LIMIT 1000

SELECT * FROM nearby u
    WHERE NOT EXISTS (SELECT * FROM relations where user_id = u.id)
    AND radius > ST_Distance(location::geography, 'my location'::geography)
    ORDER BY ST_Distance(location::geography, 'my location'::geography) * (current_timespan - last_active)

将查询拆分为两个,以确保第一部分在位置上使用地理索引。它的工作正常,只要它限制在一个合理的小数字,如1000.当第一部分返回的所有用户在第二部分被过滤掉时,问题就出现了。

有关如何重新设计此系统以使其支持数百万用户的数百万用户的任何建议吗?

整个系统与Tinder必须做的非常相似,找到您尚未与之互动的用户,并根据年龄和性别等多项属性对活动时间,位置和过滤器列表进行排序。

1 个答案:

答案 0 :(得分:3)

您可以尝试加性加权​​的voronoi图。在awvd中,重量从euklidian距离减去。也许你可以使用每个半径作为&#34;重量&#34;然后创建vd。较大的半径使较小的细胞,但它也倾向于使一个较大的细胞与附近的点。你可以寻找例子来取消。它还使用加权voronoi图!然后,您可以尝试点多边形测试,但要解决这个问题非常困难。你可以在这里阅读关于voronoi图的信息:https://alastaira.wordpress.com/2011/04/25/nearest-neighbours-voronoi-diagrams-and-finding-your-nearest-sql-server-usergroup/

enter image description here