7

我对 Objectify 还很陌生,我有一个关于做某事的最佳方法的快速问题:

假设我有一个允许人们发送和接收消息的应用程序(为简单起见考虑电子邮件)。当我的应用程序加载时,我不想加载向给定用户发送消息的每个联系人的每条消息。那将是一种浪费。相反,我想加载用户收到消息(已读或未读)的所有联系人,以便我可以在我的应用程序上显示联系人列表,当用户点击给定联系人时,我想加载所有来自该联系人的消息以显示给用户。

如果不加载帐户的所有消息,我找不到这样做的好方法。我阅读了关于多对一关系的 Objectify wiki,但我仍然想不出一个不是非常低效的好方法。对于 objectify 站点推荐的方式,我似乎必须为给定用户加载所有消息,然后解析它们以获取唯一联系人。

我正在尝试使用尽可能少的 App Engine 读取和写入,并且在可能的情况下我尝试使用 Smalls 而不是读取(在我制作这个时,运行我的应用程序的总成本是我的一个大问题) .

在 Objectify 上,我应该怎么做?

4

1 回答 1

11

这是从我对 objectify-appengine google 组的回复中复制的:https ://groups.google.com/forum/?fromgroups#!topic/objectify-appengine/LlOyRJZRbnk

在处理您所描述的“聚合数据”时,有三个主要选项:

1) 需要时计算

你已经得出结论,我认为这是正确的,这太贵了。

2)以批处理间隔计算并存储此结果

不是很令人满意,因为它涉及延迟。另外,您不想每晚都梳理整个数据库。

3)数据变化时更新聚合

每次数据更改时,这种方法都会涉及更多工作,但这几乎肯定是您想要做的。

为每个用户创建某种联系人集合。邮件到达时,请确保该收件人存在发件人联系人。也许您还想在收件人删除发件人的最后一条消息时删除联系人。

注意不要碰到实体组事务速率限制(每秒一次写入)。我将引导您完成一些选项:

1)您可以在每个收件人中存储联系人列表:

class Person {
   @Id Long id;
   Set<Key<Person>> contacts;
}

如果收件人同时收到 20 个新人的邮件,这将是一个明显的问题。这几乎可以肯定是个坏主意。另一方面,查找您的联系人是谁非常快速和高效。一个小的改进是将其移动到由该人作为父对象的单独实体中,这样您就不必总是加载该数据:

class Contacts {
   @Parent Key<Person> owner;
   @Id long id = 1;   // there's only ever one of these per person, and it should have a predictable key for fetching
   Set<Key<Person>> contacts;
}

当然,Set in a single entity 为您提供了 50,000 个条目的限制。如果您首先达到 1M 实体大小限制,它可能会略小于此值。如果您的密钥约为 20 个字符,则大致相同。如果这是一个问题,您可以允许多个联系人实体,此时您有一些类似于 Brett Slatkin 的 2009 年 Google I/O 演讲中的关系索引实体模式: http ://www.youtube.com/watch?v= AgaL6NGpkB8

2)您可以在另一个方向存储联系人列表

class Person {
   @Id Long id;
   @Index Set<Key<Peson>> contactOf;
}

这使得找出您的联系人是谁的成本更高一些 - 您需要一个仅键查询,而不是简单的按键获取。但是您不再受实体写入速率的限制。人们每秒发送的消息可能不会超过一条,如果他们批量发送 1000 条消息,您可以在单个事务中更新 contactOf。

如上所述,您可能希望将此索引移动到单独的实体中:

class Contacts {
   @Parent Key<Person> person;
   @Id long id = 1;   // there's only ever one of these per person, and it should have a predictable key for fetching
   Set<Key<Person>> of;
}

3)您还可以将这些联系人存储在一个完全独立的实体中

class Contact {
   @Parent Key<Person> person;
   @Id Long id;
   @Index Key<Person> owner;
}

这实际上只是一种空间效率较低的解决方案#2。

重要的是在发送或接收每条消息时不断更新此结构。

于 2012-02-16T17:20:19.720 回答