【问题标题】:Gql get all children of ancestor without the ancestor itselfGql获取没有祖先本身的祖先的所有孩子
【发布时间】:2011-07-23 13:04:13
【问题描述】:

我正在尝试在 GAE 上建立一个类似平台的论坛。

我必须首先提到:我对 GAE 有点陌生。

我想提取对特定帖子的所有回复。 到目前为止,结构看起来是这样的:

- Forum
--- Post
----- Reply ( = Post with Post as a parent )

回复只是以帖子为父(而不是以论坛为父)的帖子。

当我尝试拉出所有回复时,问题就开始了,返回的结果包括祖先本身。

如果没有祖先本身,我怎样才能达到同样的效果?(可能还需要提到我搜索了解决方案但没有找到)

编辑:

我的查询是这样的:

replies = db.GqlQuery("SELECT * FROM Post WHERE ANCESTOR IS :1", post)

谢谢!

更新:

嗯,我找到了办法:

db.GqlQuery("SELECT * FROM Post WHERE ANCESTOR IS :1 AND __key__ != :2", post, post.key())

只需在 where 子句中查询并排除祖先本身!

【问题讨论】:

  • 从列表中删除它?
  • 我想到了,但是没有祖先就没有办法得到它吗?
  • @juxstapose 这排除了知道结果桶何时计数为 0 的选项。
  • 您能解释一下为什么需要将它们存储在同一个实体组中吗?鉴于应用程序的性质,我无法想象论坛/帖子/回复之间的参照完整性至关重要。仅使用 ReferenceProperty 而不使用 parent 关系似乎更明智(除非我误解了什么)
  • Shlomi:你能发布你用来获得这些结果的代码吗?那将是一个很大的帮助。另外,这是 Python 还是 Java?

标签: python google-app-engine google-cloud-datastore


【解决方案1】:

您提出的解决方案在查询中使用了不等式过滤器。底层数据存储不支持不等式过滤器,它们在内部被转换为两个单独的查询,如下所示:

SELECT * FROM Post WHERE ANCESTOR IS :1 AND __key__ < :2
SELECT * FROM Post WHERE ANCESTOR IS :1 AND __key__ > :2

显然,这大大降低了效率。一个更简单、更有效的选择是简单地获取所有结果,然后丢弃您不想要的一个实体。

【讨论】:

  • 对不起,知识匮乏,但是您如何丢弃此收藏中的物品?
  • @Shlomi 通过使用列表推导,例如 - [x for x in results where x.key() != foo]。
【解决方案2】:

如果您有父键,则不必获取父帖子实体。如果您有父帖子密钥的字符串版本:

parent_post = db.Key(string_version_of_the_key)
replies = Post.all().ancestor(parent_post).fetch(num_to_fetch)

如果您有父帖子的密钥 ID 或名称:

parent_post = db.Key.from_path('Post', id_or_key_name)
replies = Post.all().ancestor(parent_post).fetch(num_to_fetch)

有关更多详细信息,请参阅Key 类的文档。

【讨论】:

  • 如果我想获取所有子帖子?
  • @Shlomi 给定父级的键、id 或名称,将仅选择“回复”(或子 Post 实体),而不需要获取父级实体。
  • 首先,这不起作用,它返回san错误,db.Model中没有祖先方法。其次,当我使用 Post.all().ancestor(parent_post) 工作但仍然返回帖子本身时,结果
  • @Shlomi,是的——丢失的 all() 是一个错字。你也对,结果中返回了父实体。
  • 无论如何谢谢 :),我想我已经找到了办法!在查询中,您还可以在 where 子句中规则键!
【解决方案3】:

我不知道您的代码是否使用 Python,但您的查询应该如下所示:

replies = Reply.ancestor(post).fetch(num_to_fetch)

这绝对不会在您的结果集中返回post,因为实体不能是它自己的祖先。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-25
    • 2013-11-22
    • 1970-01-01
    • 1970-01-01
    • 2022-07-25
    • 1970-01-01
    相关资源
    最近更新 更多