这将是一个“漫长的”。我尽可能地包含尽可能多的代码和解释......如果有必要,我不会抛出代码。在django-query中实现逻辑分析器
我想在django查询系统中实现一个逻辑分析器。用户可以针对应用于样本的标签提供复杂查询。这实质上是科学样本库的一部分,用户可以应用定义的标签(组织类型,疾病研究等)。然后,他们可以在这些标签上创建由逻辑查询定义的样本的持久性“篮子”。
#models.py
class Sample(models.Model):
name = models.CharField(max_length = 255)
class Tag(models.Model):
name = models.CharField(max_length = 255)
samples = models.ManyToManyField(Sample)
A quick example:
#example data:
Sample1 has TagA, TagB, TagC
Sample2 has TagB, TagC, TagD
Sample3 has TagA, TagC, TagD
Sample4 has TagB
#example query:
'TagB AND TagC AND NOT TagD'
将返回Sample1。我用一个疯狂的字符串-EVAL黑客创建Q()
对象的一组:
def MakeQObject(expression):
"""
Takes an expression and uses a crazy string-eval hack to make the qobjects.
"""
log_set = {'AND':'&','OR':'|','NOT':'~'}
exp_f = []
parts = expression.split()
#if there is a) or (then we can't use this shortcut
if '(' in parts or ')' in parts:
return None
for exp in parts:
if exp in log_set:
exp_f.append(log_set[exp])
else:
exp_f.append("Q(tags__name__iexact = '%s')" % exp)
st = ' '.join(exp_f)
qobj = eval(st)
return qobj
然而,这种失败在任何可被需要操作或分组的复杂顺序()。给定相同的示例数据,查询:(TagA OR TagB) AND NOT TagD
应返回Sample1,Sample4但不。我实现了一个“一次一个”的功能,它可以接受一个Sample对象并执行查询。然而,在我的实际数据库中,我有〜40,000个样本和〜400个标签(每个样本约7个),迭代技术需要大约4分钟才能完成所有样本。所以我每晚计算篮子,然后在白天冻结它们。我担心,随着我开始策划更多的篮子,样品和标签会变得很糟糕。
有什么建议吗?
我也尝试过将“()”类型的查询分解为更长的,但没有parens的等价版本,但还没有能够使这些工作。 – JudoWill 2010-01-05 05:05:46