Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何建立一个';比如';通过ndb的机制?_Python_Google App Engine_Google Cloud Datastore_App Engine Ndb - Fatal编程技术网

Python 如何建立一个';比如';通过ndb的机制?

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

我们将在我们的应用程序中引入一个社交方面,用户可以在其中喜欢彼此的活动。 如果弄错了这一点,以后会很头疼,因此我很想从一些有经验的GAE开发人员那里得到一些信息,他们会建议如何对GAE进行建模

似乎有一个类似的问题,但是OP没有提供任何代码

以下是两个模型:

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))

请您提供一个像上面这样的代码片段好吗?跟随你的想法会更容易。分割计数器是最好的方法。如果许多用户同时喜欢这篇文章,也建议这样做,以避免在同一实体上每秒更新太多。