【问题标题】:Google Datastore ancestor query returning data too far downGoogle Datastore 祖先查询返回的数据太低了
【发布时间】:2020-01-14 14:53:08
【问题描述】:

我正在开发一个“收件箱/消息”结构,它允许多种类型的父母。例如,人们可以将 cmets 留在几个不同的 kinds 对象上。对于此示例,假设有人在 Article 对象上发表评论。

按照我们格式化数据的方式,评论创建为Message 对象,并且该对象是Article 的子对象(而ArticleAccount 的子对象)。因此,当我们查询消息列表时,我们只需询问作为 Article 实例的子级的所有消息。看起来像这样:

Message.query(ancestor=source_key)

source_key 这是我们正在查看的文章的Key

太好了,这很好用,而且速度很快。

现在我们要向那些Message 对象添加回复。我想我们将像添加Messages 到Articles 一样存储回复。也就是说,回复只是Message 的另一个实例,而回复对象的父对象就是它要回复的消息。因此,基本上,您不是对文章发表评论,而是对消息发表评论。

这在纸面上听起来不错,但在实践中,它最终得到的Key 的结构如下:

Key('Account', 5629499534213120, 'Article', 5946158883012608, 'Message', 6509108836433920)

事实证明,当我们查询消息列表时,它也会在响应中返回 回复,就好像它们根本不是回复一样。

一些问题:

  • 有什么方法可以像“浅”查询那样做吗?要严格获取Article 的直系子级吗?

  • 我已经阅读了更多关于 how ancestor queries 工作的内容,并且因为祖先查询有每秒 1 次写入的限制,我现在想知道是否将我们如何将其存储到 Message 的位置会更好不是Article 的子级,而是可能在Message 上存在KeyPropertyArticle,如果这有意义的话。也许Message 没有父母。可能有很多人对一篇文章发表评论,或者也有很多人对这些 cmets 留下回复。但即便如此,Article 也是Account 的子对象,还有许多其他类型的对象,通常我们不会遇到任何不同写入的问题。那么我们是否会遇到这种写入限制?

编辑:我已经移动了一点,并试图查询 only 对给定消息的回复,所以我正在寻找所有具有另一条消息的父(祖先)的消息.

所以给定这个键作为祖先:Key('Account', 5629499534213120, 'Article', 5946158883012608, 'Message', 5663034638860288)

我查询了我们的消息表,并得到了完全相同的密钥(以及其他消息)。这怎么可能?如果我指定一个祖先,那么在什么情况下我会取回我用来查询祖先的同一个对象?该消息的父级只是:

Key('Account', 5629499534213120, 'Article', 5946158883012608)

所以,显然祖先在那里并不严格匹配。为什么我的查询会返回它呢? Hastebin 基本上我遇到了什么:https://hastebin.com/karojolisi.py

【问题讨论】:

    标签: google-cloud-platform google-cloud-datastore app-engine-ndb


    【解决方案1】:

    关于写入限制的问题,如果您在 Datastore 模式下使用 Cloud Firestore,那么每秒 1 次写入的限制是由实体而非实体组决定的。

    https://cloud.google.com/datastore/docs/firestore-or-datastore

    “对实体组的写入不再限于每秒 1 次。”

    https://cloud.google.com/datastore/docs/concepts/limits

    “对实体的最大写入速率”是“每秒 1”

    因此,无论您采用哪种方法,在数据存储模式下,写入都不应成为问题,因为不应编辑消息和回复。当然,除非您有任何类型的聚合信息,例如给定消息的回复数量,这需要使用每个子记录更新父消息记录。

    关于只查询文章消息而不查询其回复的主要问题,一种选择是有一个名为 article_id 的字段,并仅为顶级消息填充此字段,并将其也包含在索引中(祖先的前缀综合指数)。推荐 article_id 而不是布尔值的原因是,由于该字段已被索引,因此该字段最好不要基于窄范围的值。

    更喜欢这种方法将消息存储在单独的表中的原因是,属于一篇文章的所有消息都将使用初始方法存储在附近,这样可以提高阅读性能。

    【讨论】:

    • 所以你的推荐有点像我暗示的那样,在Message 上有一个KeyProperty 来存储消息附加到的文章?然后只是基于此查询?此外,在这种情况下,消息将没有父级。此外,我们没有使用 Firestore,它是一个较旧的数据库,仍然是常规的“数据存储”
    • 我已经用我遇到的关于祖先查询的新问题更新了我的问题
    • 祖先查询尝试匹配索引中键的前缀。由于所有消息(在所有级别)都是索引的一部分,因此祖先键匹配它自己的键,因此它被返回。您必须显式过滤掉它,或者添加另一个属性来过滤掉它并只获得它的响应。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-25
    • 1970-01-01
    • 2015-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多