0

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

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

Message.query(ancestor=source_key)

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

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

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

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

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

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

一些问题:

  • 有什么办法可以像“浅”查询一样吗?严格地得到那个的直系孩子Article

  • 我已经阅读了有关祖先查询如何工作的更多信息,并且由于祖先查询每秒写入 1 次的限制,我现在想知道是否可以更好地将我们如何将其存储到 a不是Message的子项,而是可能有一个存在于,如果这是有道理的。也许没有父母。可能有很多人对一篇文章发表评论,或者也有很多人对这些评论进行回复。但即便如此,与许多其他类型的对象一起是 too 的子对象,通常我们不会遇到许多不同写入的任何问题。那么我们甚至会遇到这个写入限制吗?ArticleKeyPropertyArticleMessageMessageArticleAccount

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

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

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

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

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

4

1 回答 1

2

关于写入限制的问题,如果您在 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 而不是 boolean 的原因是,由于该字段已被索引,因此该字段最好不要基于窄范围的值。

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

于 2019-09-13T00:25:38.777 回答