在 GAE Objectify 中创建通知类型提要
Creating a Notifications type feed in GAE Objectify
我正在为我的移动应用程序制作通知源,正在寻求有关问题的帮助。
该应用程序是一个 Twitter/Facebook 类应用程序,用户可以在其中 post 状态,其他用户可以喜欢、评论或订阅它们。
我想在我的应用程序中拥有一个通知提要,用户可以在其中看到谁 liked/comment 在他们的 post 上或订阅了他们。
这个系统的第一部分我已经弄明白了,当用户 likes/comments/subscribes 时,一个 Notification
实体将被写入数据存储区,其中包含有关事件的详细信息。要显示用户 Notification
,我所要做的就是查询该用户的所有 Notification
,按创建日期 desc 排序,我们有其他用户在特定用户帐户。
我遇到的问题是当有人不喜欢 post、取消订阅或删除评论时该怎么办。目前,如果我要查询该特定通知,由于最终一致性,可能 return 数据存储区中没有任何内容。我们可以想象有人喜欢,然后立即不喜欢 post(b/c 谁没有这样做过?=P)。查找 Notification
的查询可能 return 为空,并且在调用 ofy().delete().entity(notification).now();
时不会删除任何内容 现在用户在他们的提要中收到通知,说 Sally 喜欢他的 post她喜欢然后很快不喜欢的现实!
整个系统的一个问题是我无法通过 Key<Notification>
删除,因为在尝试删除时我真的没有办法知道 Notification
的 id
它。
我正在尝试的一个潜在解决方案是不删除任何 Notification
。相反,我总是写 Notification
's 并简单地指出通知是肯定的还是否定的。然后在我向特定用户显示通知的查询中,我可以以某种方式只显示正和 Notification
。这也会在数据存储上节省一些钱,因为删除实体的成本很高。
我之前解决这个问题的方法主要有以下三种:
确定性密钥
例如
{user-Id}-{post-id}-{liked-by} 赞
{user-id}-{post-id}-{comment-by}-{comment-index} 评论
这将适用于您定义的问题的大多数基本用例,但您将需要解决一些棘手的边缘情况(例如在评论被编辑和删除时管理评论索引)。这将允许按键获取和删除
- 并行数据结构
这里的想法是在一笔交易中一次创建多个实体,但要确保它们有相关的键。例如,当有人评论提要项目时,创建一个 Comment 实体,然后创建一个具有相同 ID 的 CommentedOn 实体,但使其具有评论者用户的父键。
然后,可以对CommentedOn进行强一致查询,对Comment使用相同的id进行key获取。如果这太难了,您也可以只存储一个密钥,而不是拥有匹配的 ID。每次我这样做时,在实践中拥有匹配的 ID 会更容易。
这种方法的主要限制是您实际上是在实体之外自己创建索引,虽然这可以在您需要的地方提供高度一致的查询,但事务写入的吞吐量限制可能会变得更难理解。您还需要仔细管理状态更改(如删除)。
- 实体上的州旗
假设 Notification 对象仅向用户显示发生了某事但链接到另一个实体以获取实际数据,您可以在该实体上存储状态标志(已删除、隐藏、私有等)。然后列出您的通知将是加载实体服务器端和过滤代码(或可能的后续过滤查询)的问题。
归根结底,解决方案的复杂性应该反映问题的复杂性。我会从方法 3 开始,然后在了解更完整的需求集后迁移到方法 2。这是一种更健壮和灵活的方法,但 XG 交易限制的复杂性会重新出现 - 但最终像这样的分布式提要是一个难题。
我最终所做的以及对我的特定模型有效的是,在创建 Notification
实体之前,我首先会为其分配 ID:
// Allocate an ID for a Notification
final Key<Notification> notificationKey = factory().allocateId(Notification.class);
final Long notificationId = notificationKey.getId();
然后在创建我的 Like
或 Follow
实体时,我会设置 属性 Like.notificationId = notificationId;
或 Follow.notificationId = notificationId;
然后我会保存两个实体。
稍后,当我想删除 Like
或 Follow
时,我可以这样做,同时获取 Notification
的 Id,加载 Notification
键(这样做是非常一致的),并将其删除。
另一种可能对某人有帮助的方法=D
我正在为我的移动应用程序制作通知源,正在寻求有关问题的帮助。
该应用程序是一个 Twitter/Facebook 类应用程序,用户可以在其中 post 状态,其他用户可以喜欢、评论或订阅它们。
我想在我的应用程序中拥有一个通知提要,用户可以在其中看到谁 liked/comment 在他们的 post 上或订阅了他们。
这个系统的第一部分我已经弄明白了,当用户 likes/comments/subscribes 时,一个 Notification
实体将被写入数据存储区,其中包含有关事件的详细信息。要显示用户 Notification
,我所要做的就是查询该用户的所有 Notification
,按创建日期 desc 排序,我们有其他用户在特定用户帐户。
我遇到的问题是当有人不喜欢 post、取消订阅或删除评论时该怎么办。目前,如果我要查询该特定通知,由于最终一致性,可能 return 数据存储区中没有任何内容。我们可以想象有人喜欢,然后立即不喜欢 post(b/c 谁没有这样做过?=P)。查找 Notification
的查询可能 return 为空,并且在调用 ofy().delete().entity(notification).now();
时不会删除任何内容 现在用户在他们的提要中收到通知,说 Sally 喜欢他的 post她喜欢然后很快不喜欢的现实!
整个系统的一个问题是我无法通过 Key<Notification>
删除,因为在尝试删除时我真的没有办法知道 Notification
的 id
它。
我正在尝试的一个潜在解决方案是不删除任何 Notification
。相反,我总是写 Notification
's 并简单地指出通知是肯定的还是否定的。然后在我向特定用户显示通知的查询中,我可以以某种方式只显示正和 Notification
。这也会在数据存储上节省一些钱,因为删除实体的成本很高。
我之前解决这个问题的方法主要有以下三种:
确定性密钥
例如
{user-Id}-{post-id}-{liked-by} 赞
{user-id}-{post-id}-{comment-by}-{comment-index} 评论
这将适用于您定义的问题的大多数基本用例,但您将需要解决一些棘手的边缘情况(例如在评论被编辑和删除时管理评论索引)。这将允许按键获取和删除
- 并行数据结构
这里的想法是在一笔交易中一次创建多个实体,但要确保它们有相关的键。例如,当有人评论提要项目时,创建一个 Comment 实体,然后创建一个具有相同 ID 的 CommentedOn 实体,但使其具有评论者用户的父键。
然后,可以对CommentedOn进行强一致查询,对Comment使用相同的id进行key获取。如果这太难了,您也可以只存储一个密钥,而不是拥有匹配的 ID。每次我这样做时,在实践中拥有匹配的 ID 会更容易。
这种方法的主要限制是您实际上是在实体之外自己创建索引,虽然这可以在您需要的地方提供高度一致的查询,但事务写入的吞吐量限制可能会变得更难理解。您还需要仔细管理状态更改(如删除)。
- 实体上的州旗
假设 Notification 对象仅向用户显示发生了某事但链接到另一个实体以获取实际数据,您可以在该实体上存储状态标志(已删除、隐藏、私有等)。然后列出您的通知将是加载实体服务器端和过滤代码(或可能的后续过滤查询)的问题。
归根结底,解决方案的复杂性应该反映问题的复杂性。我会从方法 3 开始,然后在了解更完整的需求集后迁移到方法 2。这是一种更健壮和灵活的方法,但 XG 交易限制的复杂性会重新出现 - 但最终像这样的分布式提要是一个难题。
我最终所做的以及对我的特定模型有效的是,在创建 Notification
实体之前,我首先会为其分配 ID:
// Allocate an ID for a Notification
final Key<Notification> notificationKey = factory().allocateId(Notification.class);
final Long notificationId = notificationKey.getId();
然后在创建我的 Like
或 Follow
实体时,我会设置 属性 Like.notificationId = notificationId;
或 Follow.notificationId = notificationId;
然后我会保存两个实体。
稍后,当我想删除 Like
或 Follow
时,我可以这样做,同时获取 Notification
的 Id,加载 Notification
键(这样做是非常一致的),并将其删除。
另一种可能对某人有帮助的方法=D