Python 在过滤器中使用NDB属性时,为什么需要在投影查询中包含NDB属性?

Python 在过滤器中使用NDB属性时,为什么需要在投影查询中包含NDB属性?,python,google-app-engine,app-engine-ndb,Python,Google App Engine,App Engine Ndb,我想知道为什么需要在投影查询中包含某些属性。我试图得到一个“foo”属性的清晰列表 Object.query(projection=[Object.foo], distinct=True) \ .filter(Object.username == user.nickname()) \ .filter(Object.bar >= value) \ .fetch() 这一个提供了一个needIndexer,即使建议的索引已经启动并运行。原因是基于bar>=值的第二个过

我想知道为什么需要在投影查询中包含某些属性。我试图得到一个“foo”属性的清晰列表

Object.query(projection=[Object.foo], distinct=True) \
    .filter(Object.username == user.nickname()) \
    .filter(Object.bar >= value) \
    .fetch()
这一个提供了一个needIndexer,即使建议的索引已经启动并运行。原因是基于bar>=值的第二个过滤器。通过删除该过滤器,查询工作得很完美,但没有达到目标

Object.query(projection=[Object.foo, Object.bar], distinct=True) \
    .filter(Object.username == user.nickname()) \
    .filter(Object.bar >= value) \
    .fetch()
这一个有效,但现在你没有一个结果,只有不同的食物,但卡瑟斯产品的食物和酒吧。这不是我们最初的目标

Object.query() \
    .filter(Object.username == user.nickname()) \
    .filter(Object.bar >= value) \
    .fetch(projection=[Object.foo])
这一个也可以,但是没有办法按“foo”分组,因此会产生一个具有重复“foo”值的列表

正如您在上面看到的,这个问题有一些解决方案,但两者都会导致更大的响应列表。如果可能的话,我想避免这种情况。因此,我有两个问题:

  • 为什么filter()中的属性有时需要包含在投影中?这对我来说毫无意义。还有,为什么这会导致一个needIndexer而不是更合适的东西
  • 有没有解决方案没有上述缺点?或者我从错误的角度处理这个问题?欢迎任何建议

  • 这是索引推荐系统的一个bug,应该在appengine的1.8.6版本中修复。问题是为了提供不同的属性,这些属性必须是排序顺序中的第一个。请注意,不等式也必须位于排序顺序的第一位。如果你有一个不等式和一个不同的投影,它们必须在同一个属性上

    投影必须在筛选器中的唯一原因是您请求的是不同的属性。您可以将其视为在同一属性上具有group by的投影。要进行此分组,必须对属性进行排序,以提供高效的重复数据消除

    执行所需查询的唯一方法是在内存中执行一些操作(正如您在问题中提到的)。另一个选择是不使用不等式过滤器,然后在内存中执行此过滤

    如果您升级到1.8.6 SDK,您应该会收到更好的(-ish)错误消息