随着时间的推移,可以将组装的团队部署到多个项目
在此示例中,我想查询分配给'活跃'仅限项目。我正在使用的代码正在运行,但我想知道是否有更高效/紧凑的方法。
模型
class Team(ndb.Model):
"""Model for representing an project team."""
teamid = ndb.StringProperty(required=True)
project = ndb.KeyProperty(kind='Project', required=True, repeating=True)
class Project(ndb.Model):
"""Model for representing a Project"""
name = ndb.StringProperty(required=True)
status = ndb.StringProperty(required=True)
查询
status = 'active'
project_query = Project.query()\
.filter(Project.status == status)
active_projects = project_query.fetch(1000, keys_only=True)
team_query = Team.query().order(Team.teamid)\
.filter(Team.projectid.IN(active_projects))
results = team_query.fetch(max_results, offset=start_at)
紧凑形式(基本上相同的东西)
team_query = Team.query().order(Team.teamid)\
.filter(Team.projectid.IN(Project.query().filter(Project.status == status)
.fetch(1000, keys_only=True)))
有更好的方法吗?
答案 0 :(得分:2)
您可以通过“冗余”在Team实体上具有project_status
属性来对数据模型进行反规范化,并保持与相应Project实体上的status
属性相同。 / p>
当然,缺点是“更改项目状态”还需要找到分配给该项目的所有团队并相应地更改其project_status(并且您可能需要多个实体组事务)。但最重要的是,将所有分配给项目的团队定位在特定状态会变得更快,只需一个简单的查询。
这种权衡对于与数据模型去标准化相关的决策非常典型。如果在您的应用程序中,项目状态变化相对较少(并且通常可能只有少数团队被分配给给定项目),而对“在特定状态下分配给项目的所有团队”的查询频繁且需要快速,那么de - 标准化将是一个值得优化的。
更加抽象化,哪些去规范化是值得的,它总是高度依赖于特定的应用程序约束 - 查询或更新很少或频繁,每个操作的性能目标是什么。你也总是付出更多数据的代价,因为有些东西是重复的。另一方面,许多应用程序具有相对罕见的写入/更新,以及非常频繁的读取/查询,这往往倾向于明智的去规范化。
答案 1 :(得分:1)
由于团队和项目之间存在多对多的关系,因此您可以选择是否与团队合作:
project = ndb.KeyProperty(kind='Project', required=True, repeating=True)
或项目:
team = ndb.KeyProperty(kind='Team', required=True, repeating=True)
您可以通过仅使用一个查询和ndb.get_multi()来改进查询中的查询。查询很慢,获取速度更快(尤其是在memcached时)。通过更改模型,您可以改善查询。
class Team(ndb.Model):
"""Model for representing an project team."""
teamid = ndb.StringProperty(required=True)
class Project(ndb.Model):
"""Model for representing a Project"""
name = ndb.StringProperty(required=True)
status = ndb.StringProperty(required=True)
team = ndb.KeyProperty(kind='Team', required=True, repeating=True)
现在您可以按状态查询并执行get:
status = 'active'
project_query = Project.query()\
.filter(Project.status == status)
active_projects = project_query.fetch(1000, keys_only=True)
teams = set()
for project in active_projects:
teams.extend(project.team)
results = ndb.get_multi(list(teams))
(感谢Tim Hoffman对这种方法的评论。)