【问题标题】:In ndb, how to query for items where property A is not in list B?在ndb中,如何查询属性A不在列表B中的项目?
【发布时间】:2013-11-30 20:16:59
【问题描述】:

在 ndb 中,为了查询属性 A 在列表 B 中的项目,您可以执行以下操作:

Item.query(Item.A.IN(B))

如何查询列表 B 中属性 A 的项目?

【问题讨论】:

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


    【解决方案1】:

    这是不可能的。请注意,对于列表 B 中的每个项目,您的 IN 查询实际上会自动分解为多个不同的 EQUALS 查询,并返回合并的结果。

    您可以查询所有,然后手动过滤掉并忽略列表 B 中的结果。

    典型的 GAE 解决方案是对另一个易于索引和查询的值进行非规范化和预计算,并将其保存为 Item 中的属性。

    【讨论】:

      【解决方案2】:

      永远不要说永远!

      通过构建一系列 'x!=y AND x!=z' ndb 过滤器,我们可以模拟一个 'NOT IN' 查询:例如 (1):

      checkList = ['cookieAck', 'newkey', 'tempCelsius']
      query = UserSetting.query(Setting.name!=checkList[0])
      for check in checkList[1:]:
        query = query.filter(ndb.AND(UserSetting.name!=check))
      
      settings = query.fetch()
      

      实际上,这类似于以下手动构造的查询 (2):

        query = UserSetting.query(ndb.AND(ndb.AND(UserSetting.name!='cookieAck', UserSetting.name != 'newkey'), UserSetting.name != 'tempCelsius'))
      

      请注意,简单地执行以下操作也有效 (3):

      query = UserSetting.query(UserSetting.name!='cookieAck', UserSetting.name != 'newkey', UserSetting.name != 'tempCelsius')
      

      结果查询:

      Query(kind='UserSetting', filters=OR(AND(FilterNode('name', '<', 'cookieAck'), FilterNode('name', '<', 'newkey'), FilterNode('name', '<', 'tempCelsius')), AND(FilterNode('name', '<', 'cookieAck'), FilterNode('name', '<', 'newkey'), FilterNode('name', '>', 'tempCelsius')), AND(FilterNode('name', '<', 'cookieAck'), FilterNode('name', '>', 'newkey'), FilterNode('name', '<', 'tempCelsius')), AND(FilterNode('name', '<', 'cookieAck'), FilterNode('name', '>', 'newkey'), FilterNode('name', '>', 'tempCelsius')), AND(FilterNode('name', '>', 'cookieAck'), FilterNode('name', '<', 'newkey'), FilterNode('name', '<', 'tempCelsius')), AND(FilterNode('name', '>', 'cookieAck'), FilterNode('name', '<', 'newkey'), FilterNode('name', '>', 'tempCelsius')), AND(FilterNode('name', '>', 'cookieAck'), FilterNode('name', '>', 'newkey'), FilterNode('name', '<', 'tempCelsius')), AND(FilterNode('name', '>', 'cookieAck'), FilterNode('name', '>', 'newkey'), FilterNode('name', '>', 'tempCelsius'))))
      

      【讨论】:

      • 我不确定这是一个好的解决方案,因为查询可能很慢,但它似乎确实有效。
      猜你喜欢
      • 2019-08-25
      • 2016-07-14
      • 1970-01-01
      • 1970-01-01
      • 2011-06-25
      • 1970-01-01
      • 1970-01-01
      • 2012-12-26
      • 2020-11-14
      相关资源
      最近更新 更多