如何进行地理距离查询仅返回我尚未“喜欢”的结果、Elastic Search、Dynamo DB
Posted
技术标签:
【中文标题】如何进行地理距离查询仅返回我尚未“喜欢”的结果、Elastic Search、Dynamo DB【英文标题】:How to make a geo distance query only return results that I have not yet "Liked", Elastic Search, Dynamo DB 【发布时间】:2019-05-30 15:14:10 【问题描述】:我正在尝试查询我的数据库以编译给定用户喜欢/不喜欢的位置附近的帖子列表。
allPostsNearLocationUserHasLiked(
userId: ID,
location: LocationInput,
radius: Int
): [Post]
allPostsNearLocationUserHasNotLiked(
userId: ID,
location: LocationInput,
radius: Int
): [Post]
为此,我目前正在使用 AWSAppSync,将 dynamoDB 流式数据传输到 Elastic Search。这使我可以轻松地进行地理空间搜索并获取给定位置附近的所有帖子。
我想知道使用 dynamoDB 计算这个最有效的方法是什么?还是为我的喜欢/用户切换到 SQL 数据库更适合我?
我有一个用户、帖子和喜欢的 DynamoDB 表。我正在考虑使用管道解析器来:
1) 获取用户位置附近的所有帖子列表(弹性搜索)
2) 查询点赞表,得到我点过的所有点赞(DynamoDB)
3) 逐项合并结果。
我对这个特别是第 3 步的性能表示严重怀疑,这是一个 O(M*N) 操作。
有没有办法在 Elastic Search 中本地完成整个查询?
## DynamoDB Table?? Or maybe SQL?
type Like
likeId: ID!
userId: ID!
likedPostId: ID!
type Query
#Implement with Elastic Search
allPostsNearLocation(location: LocationInput, radius: Int): [Post]
## Elastic search???
allPostsNearLocationUserHasLiked(
userId: ID,
location: LocationInput,
radius: Int
): [Post]
allPostsNearLocationUserHasNotLiked(
userId: ID,
location: LocationInput,
radius: Int
): [Post]
type Location
lat: Float!
lon: Float!
input LocationInput
way: Float!
lon: Float!
type Mutation
putPost(
author: String!,
title: String!,
content: String!,
location: LocationInput!,
url: String!
): Post
putUser(name:String): User
likePost(userId: ID!, postId: ID!): Like
#DynamoDB Table
type User
userId: ID!
name: String
likes: [Like]
#DynamoDB table
type Post
id: ID!
author: String!
title: String!
content: String!
url: String!
location: Location!
schema
query: Query
mutation: Mutation
【问题讨论】:
【参考方案1】:您最初的解决方案对我来说很有意义,尽管对延迟的担忧可能被证明是有效的。你看过relational data sources吗?目前,它仅支持 Aurora Serverless,因此您对 SQL 作为替代方案的评论将是这种情况,使用它内置于地理空间数据类型而不是 Elasticsearch 中。
您可以通过这种方式完全在 RDS 中构建架构,从而无需管道。使用连接的复杂 SQL 查询可以根据位置构建您的帖子组合,而不是通过三部分工作来完成。
【讨论】:
【参考方案2】:我不确定您的性能要求是什么,但我认为您的初始计划应该没问题,如果:
1) 获取用户位置附近的所有帖子列表(弹性搜索)
这应该很快,如果 Elasticsearch 索引设置了正确的映射、大小、分片和硬件取决于数据大小。
2) 查询点赞表,获取我点过的所有点赞(DynamoDB)
这可能会很快,以防您有一个“喜欢”的内存缓存,可以是完全在内存中,也可以是惰性/LRU 缓存。
3) 逐项合并结果。
如果结果大小不是太大(使用 10-100 个项目的页面?),那么从 Elasticsearch 获取响应,在该流上运行并根据内存中的字典对其进行丰富/过滤应该没问题。
祝你好运!
【讨论】:
这是我决定的方法,目前,它应该可以很好地扩展。为了更详细地描述它,我使用了一个管道解析器,其中一个函数查询所有用户的喜好。在响应映射中,我将喜欢的列表复制到地图中,并将其存储起来以备后用。然后另一个函数使用 Elasticsearch 进行地理空间搜索。最后在 after mapping 中,我遍历每个帖子,看看它是否已经在 likes 地图中。如果有某种方法可以缓存隐藏的点赞地图,那就太好了,这样我就可以对结果进行分页,而无需重新计算。以上是关于如何进行地理距离查询仅返回我尚未“喜欢”的结果、Elastic Search、Dynamo DB的主要内容,如果未能解决你的问题,请参考以下文章