如何将键列表与实体关联

时间:2016-04-08 18:43:49

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

基本上我有一个用户实体,该用户将拥有粉丝。我可以想到如何对此进行建模的一种可能方式是使用Key类型的多值属性,它将跟随者的Keys存储在列表中。

喜欢这个..

DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();

Entity userEntity;

Key k = entity.getKey();

Entity user = new Entity("User");
List<Key> followers = new ArrayList<Key>();
followers.add(k);
user.setProperty("FollowersList", followers);
datastore.put(user);

我在某处读到App Engine将您限制为多值属性中的5,000个条目,这是我绝对不想要的。

我是NoSQL数据库的新手。我该怎么做?

2 个答案:

答案 0 :(得分:2)

如果列表已编入索引或频繁更改,则存储值列表不是一个好主意。

每次更改都会触发重新保存实体,这将导致不必要的写入成本。现在谷歌改变了它们的定价模式,所以它不像以前那么昂贵,但它仍然需要牢记。

此外,用户实体本身变大 - 每次需要此实体时,您将移动所有这些数据,即使在大多数用例中您不需要5,000个关注者列表。

一种可能的解决方案是创建一个名为“Follower”的实体类型。这些实体将没有属性(除非您需要存储关于每个关系的一些额外数据)。这些实体将是用户实体的子实体,其ID将与关注者的ID匹配。

Key userKey = KeyFactory.createKey("User", userID);
Entity followerEntity = new Entity("Follower", followerUserID, userKey);
datastore.put(followerEntity);

现在,您可以通过运行仅限密钥(可能是最便宜和最快的选项)祖先查询来快速检索所有关注者的列表:

Query q = new Query("Follower").setAncestor(userKey).setKeysOnly();

如果您删除作为其父级的“用户”实体,请不要忘记删除“关注者”实体 - 它不会自动发生,它们只会保持孤立状态。

答案 1 :(得分:1)

恕我直言,将密钥存储到用户选择关注的领导者中会更好(从可扩展性角度来看)。我认为用户不太可能追随5000名领导者:)

通过查询领导者列表中具有领导者密钥的用户,您将获得领导者的粉丝...

如果您不想存储密钥列表(如Andrei所建议的那样),您可以使用另一种实体类型将关系存储为leader_key, follower_key对。

在这种情况下,您将使用关于领导者密钥为leader_key的关系的查询并从查询结果中的每个关系中提取一个跟随键来获取领导者关注者的密钥列表(follower_key属性)。