我正在app引擎上编写一个系统来收集“样本”并提供查询和分析样本的服务。样本的数据模型与此类似:
class Sample(ndb.Model):
category = ndb.StringProperty()
name = ndb.StringProperty()
data = ndb.JsonProperty()
timestamp = ndb.DateTimeProperty()
tags = ndb.StringProperty(repeated = True)
如您所见,每个样本都有一组字符串标记。例如:
['CustomerA', '2.0.5', 'featureX', 'logTypeB', ...]
我有一个处理程序,允许根据基本属性上的过滤器查询系统中的所有样本,并包括一组要求的标记。注意:结果集可能非常大,因此查询支持分页/限制,因此我一次返回一点数据。一切正常。
现在,当我在此基础上放置用户界面时,我想要一种向用户显示自动填充字段的方法,以输入其他标签以进一步过滤结果。因此,例如,如果他们将其限制为具有以下标记的样本:
Sample(..., tags=['CustomerA', '2.0.5', 'featureX'])
Sample(..., tags=['CustomerA', '2.0.5', 'featureY'])
Sample(..., tags=['CustomerB', '2.0.5', 'featureX'])
Sample(..., tags=['CustomerB', '2.0.5', 'featureX'])
Sample(..., tags=['CustomerB', '2.0.5', 'featureY'])
然后我想向他们展示一个包含以下内容的自动填充:
['CustomerA', 'CustomerB', '2.0.5', 'featureX', 'featureY']
换句话说,我需要一个处理程序,它可以返回当前结果集中存在的唯一标记列表。问题是我无论如何都无法在App Engine中看到这样做而不迭代所有结果样本(可能非常大)并构建一组唯一标记来返回。
我可以为系统中的所有标记保留一组单独的实体,但这也不能解决问题。它允许我快速找到系统中所有样本上存在的所有标记,但不能将其限制为通过当前过滤器的样本集。
关于我能以合理的方式实现这一目标的任何想法?
答案 0 :(得分:1)
执行此操作的最佳方法是将标记保存在单独的实体中,该实体仅用于自动完成。由于标记名称是唯一的,因此您可以将标记用作实体键。使用ndb模型钩子可以使这变得简单。例如:
class SampleTag(ndb.Model):
tag = ndb.StringProperty()
class Sample(ndb.Model):
category = ndb.StringProperty()
name = ndb.StringProperty()
data = ndb.JsonProperty()
timestamp = ndb.DateTimeProperty()
tags = ndb.StringProperty(repeated = True)
def _pre_put_hook(self):
for tag in self.tags:
SampleTag.get_or_insert(name=tag)
然后,您可以使用SampleTag中的值显示在自动填充中。
这只是一个例子 - 它效率不高,特别是如果你有很长的标签列表。要改进它,您应该确定自上次保存以来添加了哪些标记(如果有的话),并且只循环执行这些标记。此外,您可能希望使用异步调用,或者可以将_pre_put例程完全委托给任务队列,这将加快放置()模型所需的时间。
此外,这不会处理删除。这有点棘手,因为您无法事先知道标签是否存在于其他地方。为此,我将使用cron作业定期检查您的标签是否存在。