【问题标题】:How to order an ndb query by a repeated field that can be empty如何通过可以为空的重复字段对 ndb 查询进行排序
【发布时间】:2014-07-08 17:55:30
【问题描述】:

我有一个带有重复属性的 ndb 模型:

class MyModel(ndb.Model):

  foo = ndb.KeyProperty(repeated=True)

我想对foo做一个不等式过滤,也就是说我需要通过foo排序:

query = MyModel.query()
query = query.filter(MyModel.foo != my_key)
# I don't actually care about doing this, but I have to because of the inequality filter.
query = query.order(MyModel.foo)

我希望查询包含 foo 为空的实体。如果我将一个虚拟字段放入 foo 中,它会起作用:

def _pre_put_hook(self):
  if not self.foo:
    self.foo.append(ndb.Key('Dummy Kind', 'Dummy ID'))

但这似乎不是一个干净的方法。有没有更好的办法?

【问题讨论】:

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


    【解决方案1】:

    当数据存储在其索引中存储带有repeated=True 的属性时,它是stores one row for each value。这意味着如果您有一个空的重复属性,它将不会显示在您的 EntitiesByProperty 索引中。这意味着无法查询空的重复属性。

    有几个选项,但它们都有自己的权衡:

    添加一个虚拟值。

    您建议的这种方法的好处是您现有的查询将为您提供所需的结果。但是,当您添加真实数据时,您必须处理清理虚拟密钥。

    使用ComputedProperty

    您可以为 foo 属性的大小添加一个新属性:

    class MyModel(ndb.Model):
      foo = ndb.KeyProperty(repeated=True)
      foo_len = ndb.ComputedProperty(lambda self: len(self.foo))
    

    但是,要获取 foo 值与 my_key 不匹配或为空的实体,您必须编写两个查询来获取结果:

    ndb.gql("SELECT * FROM MyModel WHERE foo != :1", my_key)
    ndb.gql("SELECT * FROM MyModel WHERE foo_len == :1" 0)
    

    请注意,如果 foo 没有重复,则使用以下查询将为您提供所需的结果:

    ndb.gql("SELECT * FROM MyModel WHERE foo != :1", my_key)
    

    即使没有空列表大小写,在使用重复属性时也需要小心。特别是,只有一个重复的属性必须与您的密钥匹配。因此,自 my_key2 != my_key 以来,下面定义的模型仍将匹配您的查询:

    MyModel(foo=[my_key, my_key2])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-13
      • 2020-08-31
      • 1970-01-01
      • 2013-04-20
      • 2018-03-15
      • 1970-01-01
      相关资源
      最近更新 更多