Firestore 数据建模和查询类似 Tinder 的应用程序

czp*_*lip 5 data-modeling nosql firebase google-cloud-firestore

为了让事情更简单,假设应用程序只有 2 个实体:theuser和 the post,它们是用户创建的内容。

用户可以做三件事:

  1. 创建帖子
  2. 在帖子上滑动,喜欢或不喜欢
  3. 取消关注帖子的作者,以便他/她不再看到作者的帖子

我的问题是:如何posts根据作者是否被我取消关注来查询?

我对数据建模的第一种方法

users/{userId}
- userId

posts/{postId}
- author <userId>
- content

unfollows/{userId}
- userId
- unfollowedUserId

likes/{postId_userId}
- postId
- userId

dislikes/{postId_userId}
- postId
- userId
Run Code Online (Sandbox Code Playgroud)

查询帖子:

// get all userIds that I unfollow

const unfollows = collection('unfollows').where('userId', '==', 'myUserId');
Run Code Online (Sandbox Code Playgroud)

但是后来我不知道如何有效地posts使用unfollows用户 id 数组进行查询。

// This doesn't seem correct and
// I don't know how to write the `where` filters programmatically:

// assume unfollows is already sorted.
const unfollows = collection('posts')
  .where('author', '<', unfollows[0]).where('author', '>', unfollows[0])
  .where('author', '<', unfollows[1]).where('author', '>', unfollows[1])
  ...
Run Code Online (Sandbox Code Playgroud)

第二种方法

添加unfollowedBy字段,posts其中是用户取消关注作者并在post创建时填充并在新时更新的地图unfollows

users/{userId}
- userId

posts/{postId}
- author <userId>
- content
- unfollowedBy <Map with userIds as keys>

unfollows/{userId}
- userId
- unfollowedUserId

likes/{postId_userId}
- postId
- userId

dislikes/{postId_userId}
- postId
- userId
Run Code Online (Sandbox Code Playgroud)

这使我可以查询posts

collection('posts').where(`unfollowedUserId.${myUserId}`, '==', null);
Run Code Online (Sandbox Code Playgroud)

但是,这种方法存在一些问题:

  1. unfollowedBypost文档中不会缩放,因为 的大小unfollowedBy与用户群的大小成正比。我知道任何将增长到无限大小的东西都应该是一个子集合,而不是文档中的地图,但是通过创建unfollowedBy一个子集合,我无法再posts使用它进行查询。
  2. post如果作者经常被取消关注,为了使unfollowedBy地图保持最新,该文档将经常更新。
  3. 任何用户都需要获得更新unfollowedBy其他帖子字段的权限,这并不理想,否则我将不得不创建一个云功能来处理取消关注。