谷歌应用引擎中的ndb.OR操作

时间:2013-11-21 04:44:23

标签: google-app-engine python-2.7 app-engine-ndb

我正在开发项目,我需要在降序中执行ndb.OR操作,但对于下面的代码,我收到的错误是这样的:

BadRequestError:第一个排序属性必须与应用不等式过滤器的属性相同。在您的查询中,第一个排序属性是TestNo,但不等式过滤器在Math

class StudentMarks(ndb.Model):
    Math = ndb.IntegerProperty()
    Science = ndb.IntegerProperty()
    English = ndb.IntegerProperty()
    Social = ndb.IntegerProperty()
    TestNo = ndb.IntegerProperty()

@classmethod
def queryData(cls):
    return cls.query(ndb.OR(ndb.OR(cls.Math > 0, cls.Science > 0),
                     ndb.OR(cls.English > 0 , cls.Social > 0))).order(-cls.TestNo)

是否有其他方法可以实现此方法。

1 个答案:

答案 0 :(得分:2)

如果不了解您的用例,我可以提出两种方法。

  1. 事后在内存中排序 - 如果您有数千个实体,这将无法扩展。
  2. 使用AND AND子句和TestNo作为第一个不等式过滤器(例如TestNo > -1)和OR子句的第二部分。
  3. 另一种方法可能是更改或添加存储的数据,以便您可以使用相等过滤器。您似乎正在寻找数学,科学,英语等各种组合,其值大于0.考虑添加一个ComputedProperty,它存储一个真的数学,科学等的布尔值> 0,如果== 0则为false,那么您可以将查询重写为 类似以下内容。 (我正在使用属性名称,例如hasMath用于计算属性)

    Computed Property看起来像

    hasMath = ndb.ComputedProperty(lambda self: self.Math > 0)    
    

    查询将是

    cls.query(ndb.OR(ndb.OR(cls.hasMath == True, cls.hasScience == True),
                     ndb.OR(cls.hasEnglish == True , cls.hasSocial == True))).order(-cls.TestNo)
    

    进一步查看您的查询,可以将计算属性减少为单个属性,以满足您的查询要求。

     hasClass = ndb.ComputedProperty(lambda self: self.Math > 0 or self.Science > 0 or self.English > 0 or self.Social > 0)
    

    您的查询将是

     cls.query(cls.hasClass == True).order(-cls.TestNo)
    

    假设这是您要执行的唯一此类查询,那么最后一个选项将是表现最佳且成本最低的选项。