【问题标题】:ndb.OR operation in google app engine谷歌应用引擎中的ndb.OR操作
【发布时间】:2013-11-21 04:44:22
【问题描述】:

我正在处理需要按降序执行 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)

有没有其他方法可以实现这个方法。

【问题讨论】:

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


    【解决方案1】:

    在不了解您的用例的情况下,我可以提出两种方法。

    1. 事后在内存中排序 - 如果您有数千个实体,这将无法扩展。
    2. 使用 AND 子句和 TestNo 作为第一个不等式过滤器(例如,TestNo > -1)和 OR 子句的第二部分。

    另一种方法可能是更改或添加存储的数据,以便您可以使用相等过滤器。似乎您正在寻找值大于 0 的数学、科学、英语等的各种组合。考虑添加一个 ComputedProperty,它存储数学、科学等的布尔值的 true 为 > 0,如果 == 0 则为 false ,那么您可以将查询重写为 类似于以下内容。 (我在计算属性中使用了类似 hasMath 的属性名称)

    计算属性看起来像

    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)
    

    假设这是您要执行的唯一此类查询,则最后一个选项将是性能最佳且索引成本最低的选项。

    【讨论】:

    • 你的意思是这样的:return cls.query((ndb.AND(cls.TestNo > 0), ndb.OR(ndb.OR(cls.Math > 0, cls.Science > 0) ),ndb.OR(cls.English > 0 , cls.Social > 0)))).order(-cls.TestNo)
    • 是的,类似的。不确定它是否能满足您的需求,但值得一试,因为现在您可以指定所需的排序顺序
    • 但可能值得重新审视您的用例以及您存储数据的方式。因为您可以将过滤器重新设计为使用相等过滤器。请参阅我的答案的补充内容。
    • 另一个明显的问题,为什么 OR'ing 多个 OR' 语句。本质上,查询将在 OR 语句上,或者根据计算属性建议,如果任何类的值 > 1,则存储 True 的单个计算属性。
    • 我什至想要每个属性的整数值,例如:数学 = 50、科学 = 30、英语 = 44 等,按 TestNo 的降序排列作为查询结果。
    猜你喜欢
    • 1970-01-01
    • 2011-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多