【问题标题】:How to find objects where the key is NOT in a StringListProperty in GoogleAppEngine如何在 GoogleAppEngine 的 StringListProperty 中查找键不在的对象
【发布时间】:2011-08-14 03:32:15
【问题描述】:

我很确定上述内容不可能直接实现(但我很乐意犯错)。所以这就是我想要做的,但我不知道如何让有用的查询工作。

class Challenge(db.Model):
    name = db.StringProperty()
    players = db.StringListProperty(default=[])
    created_on = db.DateTimeProperty(auto_now_add=True)
    completed_on = db.DateTimeProperty(default=None)

可能有数以千计的挑战。您可以随时加入任意数量的个挑战(在“完成”之前,但你只能参加任何一次挑战。

编辑------------------

挑战是异步完成的(它们可能会持续数天),并在该阶段结束时决定“获胜者”,因此人们可能同时面临多个挑战,等待这些挑战结束。基本上,您加入挑战并完成任务,然后等待其他人也这样做,然后在挑战结束时选择获胜者。在等待期间,您可以加入并完成其他挑战。每个挑战的人数限制为 250-500 人(尚未确定上限)

------------------编辑

我想列出您可以参加的所有挑战,按created_on 排序。 playersstr(user.key()) 的列表,供所有参加挑战的人使用。

你可以这样做:

already_in = Challenge.all().filter('players = ', str(self.user.key())).filter('completed_on =', None)
already_in_set = set()    
for challenge in already_in.fetch(1000):
    already_in_set.add(str(challenge.key()))  # Could cache this in the user object

challenges = Challenge.all().order('created_on')
keepers = []
for challenge in challenges:
    if str(challenge.key()) not in already_in_set:
        keepers.append(challenge)
        if len(keepers) > 11:
            break

现在keepers 有你不在的列表。但是上面的代码感觉不是很优化。

当然还有另一种方法可以做到这一点。 (我也不反对重组数据库以使其更好地工作)

我可以将 already_in_set 作为 StringListPropery(indexed=False) 缓存在 User 对象上,这样可以加快速度,但是我必须修剪它以删除现在已完成的挑战(我可以在UI 请求)。

我希望我遗漏了一些关于如何使用 AppEngine 数据存储进行查询的明显内容。

【问题讨论】:

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


    【解决方案1】:

    如您所料,这实际上是不可能的。列表属性中的元素是单独索引的,因此“不等于 x”的过滤器将返回至少有一个值不等于 x 的任何列表,而不是所需的结果。

    不过,鉴于您所描述的情况,用户似乎不太可能面临无穷无尽的挑战。获取他们已经面临的挑战,并将这些结果从结果集中过滤出来,似乎是一个合理的解决方案。如果您想让事情变得更高效,您可以存储针对用户的挑战列表,而不是反之亦然。这也意味着可以参与给定挑战的用户数量不再有实际限制。

    最后,不要使用 db.StringListProperty 来存储序列化密钥 - 而是使用 db.ListProperty(db.Key)

    【讨论】:

      【解决方案2】:

      鉴于用户一次只能加入一个挑战,如果您记录用户参与的未完成挑战(如果有),您可以非常有效地检索它。然后(如果我理解正确的话)两种情况之一适用:用户已经参加了挑战,在这种情况下不需要查询挑战,或者您确实需要查询可用的挑战。要执行后一个查询,在 Challenge 中存储 completed 标志可能会有所帮助。

      这意味着您必须在挑战完成后做一些额外的记账,找到所有参与的用户并取消他们的参与。

      【讨论】:

      • 我编辑了描述以表明您可以同时参与多个挑战。和你一起挑战的人数可能很大。抱歉,我一开始没有说明。
      猜你喜欢
      • 1970-01-01
      • 2011-08-15
      • 2018-12-19
      • 2020-01-19
      • 2018-03-21
      • 1970-01-01
      • 2017-11-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多