App引擎数据存储:如何实现没有连接的帖子和标签?

Dam*_*ian 10 java google-app-engine database-design google-cloud-datastore

我正在使用Google App Engine(Java)构建一个应用程序,用户可以在其中发帖,我正在考虑为这些帖子添加标签,所以我会这样:

在实体邮政:

public List<Key> tags;
Run Code Online (Sandbox Code Playgroud)

在实体标签:

public List<Key> posts;
Run Code Online (Sandbox Code Playgroud)

例如,查询具有特定标签的所有帖子会很容易,但我怎样才能获得包含标签列表的所有帖子?我可以对每个标签进行查询,然后对结果进行交集,但也许有更好的方法......因为很多帖子都会很慢.

另一件可能更难的事情是有一个帖子,获得具有通用标签数量的共同标签的帖子,所以我可以以某种方式获得"相似"的帖子.

好吧,通过连接,这将更容易,但我开始使用app引擎,并且无法真正考虑更换连接的好方法.

谢谢!

Pet*_*ore 5

有了这种设计,我担心你的标签实体可能成为瓶颈,特别是如果你期望某些标签非常普遍.我能想到的三个具体问题是你的获取和放置的效率,写入争用和爆炸式索引.让我们看看stackoverflow的一个例子 - 现在有14,000个帖子被标记为"java".

  1. 这意味着每次需要获取java标记实体时,您都会从数据存储中提取14k的关键数据.然后当你进行投注时,你会把它全部寄回去.这可能会增加很多字节.
  2. 除了来回的字节之外,每个put都需要更新索引.ListProperty中的每个条目都映射到单独的索引条目.所以现在你正在进行大量的索引更新.这导致我们排名第3 ...
  3. 爆炸指数.每个实体都有一个限制,它可以有多少索引条目.我认为每个实体的限制是5000.所以这实际上是对有多少帖子可能具有相同标签的硬性限制.

进一步阅读:

好消息是,只有Post实体可以轻松处理您的一些要求.例如,您可以使用查询过滤器轻松找到包含所有标记列表的所有帖子,如下所示:

Query q = pm.newQuery(Post.class)
q.setFilter("tags" == 'Java' && "tags == 'appengine'");
Run Code Online (Sandbox Code Playgroud)

对于所有帖子或者 Java或AppEngine上的标签,你就需要为每个标签做一个查询,然后结合自己的结果.数据存储区现在不处理OR/IN类型操作.

找到相关的帖子听起来很棘手.喝咖啡后我会考虑一下.