Python 如何建立一个';比如';通过ndb的机制?
我们将在我们的应用程序中引入一个社交方面,用户可以在其中喜欢彼此的活动。 如果弄错了这一点,以后会很头疼,因此我很想从一些有经验的GAE开发人员那里得到一些信息,他们会建议如何对GAE进行建模 似乎有一个类似的问题,但是OP没有提供任何代码 以下是两个模型:Python 如何建立一个';比如';通过ndb的机制?,python,google-app-engine,google-cloud-datastore,app-engine-ndb,Python,Google App Engine,Google Cloud Datastore,App Engine Ndb,我们将在我们的应用程序中引入一个社交方面,用户可以在其中喜欢彼此的活动。 如果弄错了这一点,以后会很头疼,因此我很想从一些有经验的GAE开发人员那里得到一些信息,他们会建议如何对GAE进行建模 似乎有一个类似的问题,但是OP没有提供任何代码 以下是两个模型: class Event(ndb.Model): user = ndb.KeyProperty(kind=User, required=True) time_of_day = ndb.DateTimeProperty(requ
class Event(ndb.Model):
user = ndb.KeyProperty(kind=User, required=True)
time_of_day = ndb.DateTimeProperty(required=True)
notes = ndb.TextProperty()
timestamp = ndb.FloatProperty(required=True)
class User(UserMixin, ndb.Model):
firstname = ndb.StringProperty()
lastname = ndb.StringProperty()
我们需要知道谁喜欢某个事件,以防用户可能想再次不喜欢它。因此,我们需要保留一份参考资料。但是怎么做呢
一种方法是向事件类引入RepeatedProperty
class Event(ndb.Model):
....
ndb.KeyProperty(kind=User, repeated=True)
这样,任何想要此事件的用户都将存储在这里。此列表中的用户数将决定此事件的喜欢数
理论上,这应该行得通。然而,Python创建者的这一点让我担心:
如果值超过100-1000,请不要使用重复属性。
(1000可能已经在推动了。)它们不是为这样的目标而设计的
使用
回到原点。我应该如何设计它?
RepeatProperty
在值的数量上有限制(<1000)
一种建议的打破限制的方法是使用shard
:
class Event(ndb.Model):
# use a integer to store the total likes.
likes = ndb.IntegerProperty()
class EventLikeShard(ndb.Model):
# each shard only store 500 users.
event = ndb.KeyProperty(kind=Event)
users = ndb.KeyProperty(kind=User, repeated=True)
如果限制大于1000但小于100k。
更简单的方法是:
class Event(ndb.Model):
likers = ndb.PickleProperty(compressed=True)
使用另一个“Like”模型,在该模型中保留对用户和事件的引用。
以关系方式表示多对多的旧方法。通过这种方式,您可以将所有实体分开,并且可以轻松地添加/删除/计数。鉴于设计似乎需要无限数量的用户链接事件,我建议使用
EventUser
模型建立通常的多对多关系。唯一棘手的部分是,您必须确保事件/用户组合是唯一的,这可以使用\u pre\u put\u hook
完成。按照@lucemia的建议,保留一个likes
计数器确实是个好主意
然后,您可以使用布尔值捕获喜欢的
操作,或者,您可以通过包含操作
字符串数组使其更加灵活。这样,您还可以捕获诸如注册
或参加
之类的操作
下面是一个示例代码:
class EventUser(ndb.Model):
event = ndb.KeyProperty(kind=Event, required=True)
user = ndb.KeyProperty(kind=User, required=True)
actions = ndb.StringProperty(repeated=True)
# make sure event/user is unique
def _pre_put_hook(self):
cur_key = self.key
for entry in self.query(EventUser.user == self.user, EventUser.event == self.event):
# If cur_key exists, means that user is performing update
if cur_key.id():
if cur_key == entry.key:
continue
else:
raise ValueError("User '%s' is a duplicated entry." % (self.user))
# If adding
raise ValueError("User Add '%s' is a duplicated entry." % (self.user))
请您提供一个像上面这样的代码片段好吗?跟随你的想法会更容易。分割计数器是最好的方法。如果许多用户同时喜欢这篇文章,也建议这样做,以避免在同一实体上每秒更新太多。