10

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

在实体帖子中:

public List<Key> tags;

在实体标签中:

public List<Key> posts;

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

可能更困难的另一件事是发布帖子,获取具有共同标签的帖子,按常见标签的数量排序,这样我就可以以某种方式获得与该帖子“相似”的帖子。

好吧,有了连接,这会容易得多,但我是从应用引擎开始的,真的想不出一个替换连接的好方法。

谢谢!

4

3 回答 3

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'");

对于带有 java 或 appengine 标签的所有帖子您需要对每个标签进行一次查询,然后自己组合结果。数据存储现在不处理 OR/IN 类型的操作。

查找相关帖子听起来很棘手。喝杯咖啡后我会考虑的。

于 2009-07-03T16:27:30.790 回答
1

您可能想从Google IO观看此视频。关系索引实体是您需要的,并允许您List<Key> postsTag实体上删除。以及List<Key> tagsPost实体上。

于 2009-07-09T06:43:52.257 回答
1

请参阅@topchef 的博客文章:Efficient Keyword Search with Relation Index Entities and Objectify for Google Datastore。它讨论了使用关系索引实体和 Objectify 实现具有列表属性的搜索。

于 2011-04-26T03:31:25.360 回答