在GAE上建模投票

时间:2010-11-22 20:02:21

标签: google-app-engine google-cloud-datastore

我正在尝试确定在GAE数据存储区上创建可投票实体的最有效方法。我想向用户显示一个控制权来投票给这个实体,或者一个图标表明他们已经投票赞成了这个实体;即,我问“有一个用户投票给这个实体?”假设我们有一个用户可以向上投票的问题实体。以下是我正在考虑的事情:

  1. 查询我的问题实体。这些问题已经有一个预先计算的排名,我将对此进行排序。
  2. 使用作为Question实体的子项的关系索引实体。使用与#1相同的过滤器查询所有问题,其中我的用户是此关系索引实体的成员。
  3. 通过为每个找到的集合成员设置hasVoted属性为true,将#2的结果合并到#1中。
  4. 这是我能想到的最干净的方式,但它仍然需要两个查询。我没有为每个用户创建重复的Question实体,因为它会导致过多的数据重复。这个解决方案是一个很好的方法来处理在投票和问题之间的m2m关系之间的有效连接,还是我在关系上的思考?

3 个答案:

答案 0 :(得分:3)

不是使用关系索引,而是为每个在该问题上投票的用户设置一个子实体。使子实体的key_name成为用户的ID。然后,要确定用户y是否已对ID为x的问题进行投票,只需获取密钥(问题:x /投票:y)。您可以对此进行批处理以获取多个问题或用户的多个实体。

答案 1 :(得分:2)

我会看看Overheard Google App Engine示例应用程序。

  

我们的基本模式将是   引号,包含一个字符串   报价和投票,其中包含   用户名和投票给   特别是用户。

关于它有一个Google article,你可以找到here来源。

答案 2 :(得分:0)

要避免第二个查询,您可以将用户在一个实体中投票的所有问题存储起来。此实体可以是User模型的一部分,也可以与User实体以一对一的关系存在。

然后,您可以根据需要加载此信息(并将其存储到内存缓存以避免数据存储加载),以便您可以快速检查用户是否已经对某个问题进行了投票(大部分时间都没有进行第二次查询)。 / p>

如果用户可以对大量问题进行投票,那么您可能需要扩展这个想法。这是一个关于简单方案的大纲(非功能完整):

class UserVotes(db.Model):
    # key = key_name or ID of the corresponding user entity

    # if all of your question entities have IDs, then voted_on can be a list of 
    # integers; otherwise it can be a list of strings (key_name values)
    voted_on = db.ListProperty(int, indexed=False)  

# in your request handler ...
questions = ...
voted_on = memcache.get('voted-on:%s' % user_id)
if voted_on is None:
    voted_on = UserVotes.get_by_id(user_id)  # should do get_or_insert() instead
    memcache.set(...)
for q in questions:
    q.has_voted = q.key().id() in voted_on