我有一个问题,我现在正在努力一段时间。我正在尝试使用GAE云端点和Java在我的应用中实现新闻Feed功能。常见的概念是追随者和追随者,其追随者可以看到追随者的行为。一个新的追随者也应该看到他的追随者过去的行动,而不仅仅是他开始追随的时候。
我尝试了以下组件。每次尝试都很有效,但缺乏一些东西:
所以我要求stackoverflow社区的建议。你能告诉我这件事吗?如果准备搜索是正确的选择,您能否提供一些使用云端点的明确示例Java代码?
编辑:只是为了强调此处的主要设计要求 - 新闻Feed功能需要能够使用游标获取已排序的跟随者动作(以避免查询整个批次)。
答案 0 :(得分:2)
使用pull-aggregate-per-follower模型:定期(或按需)查询所有跟随者操作一次,然后将其缓存在专用的每个跟随者实体中。记住上次查询的时间,因此下次您只需从该点开始查询(假设操作无法添加/更改为过去的时间)。
这将为您提供以下功能(和限制):
get
加载到内存中。这应该是一个可观的成本和时间。限制:
答案 1 :(得分:0)
我希望我能正确理解这个问题 - 您希望在您的应用中实施新闻Feed,并允许用户互相关注。新粉丝需要能够看到用户的操作。我确信有多种其他方法可以解决这个问题,但我会尝试通过提供一个使用JAVA JDO来访问数据存储区的解决方案来帮助您。
我首先设计entity relationships in JDO如下:
1 User to many actions.
1 User to many followers (User).
1 User to many following (User).
以下是简单的JDO类:
用户类:
@PersistenceCapable(identityType=IdentityType.APPLICATION)
public class User {
@PrimaryKey
@Persistent(valueStrategy=IdGeneratorStrategy.IDENTITY)
private Key key;
@Persistent
private String userId; // Google unique user ID, could also store user email.
@Persistent
private Set<Key> actions;
@Persistent
private Set<Key> followers;
@Persistent
private List<Key> following;
public User(Key key, String userId) {
this.key = key;
this.userId = userId;
this.actions = new HashSet<Key>();
this.followers = new HashSet<Key>();
this.following = new HashSet<Key>();
}
public Key getKey() {
return this.key;
}
public void addAction(Key actionKey) {
this.actions.add(actionKey);
}
public void addActions(Set<Key> actionKeys) {
this.actions.addAll(actionKeys);
}
public Set<Key> getActions() {
return this.actions;
}
public void addFollower(Key followerKey) {
this.followers.add(followerKey);
}
public void addFollowers(Set<Key> followerKeys) {
this.followers.addAll(followerKeys);
}
public Set<Key> getFollowers() {
return this.followers;
}
public void addFollowing(Key followingKey) {
this.following.add(followingKey);
}
public void addAllFollowing(Set<Key> followingKeys) {
this.following.addAll(followingKeys);
}
public Set<Key> getFollowing() {
return this.following;
}
}
行动类:
@PersistenceCapable(identityType=IdentityType.APPLICATION)
public class Action {
@PrimaryKey
@Persistent(valueStrategy=IdGeneratorStrategy.IDENTITY)
private Key key;
@Persistent
Date date;
@Persistent
private String title;
public Action(Key key, String title) {
this.key = key;
this.title = title;
this.date = new Date(); // date of creation (now).
}
public Key getKey() {
return this.key;
}
public void setTitle(String title) {
this.title = title;
}
public String getTitle() {
return this.title;
}
}
Action类使用Date属性,您可以参考documentation获取数据存储区中适用的数据类型。创建操作时a Date object is allocated and initialized so that it represents the time at which it was allocated, measured to the nearest millisecond。
在我上面的例子中,我通过他们的键链接了实体,你可以用它们的类来链接它们,如下所示:
List<Action> actions;
我的例子中的关系是一个无主的一对多关系,也许它应该是一对多的。更多信息here供您查看,或许可以决定哪种方案最适合您的解决方案。
一旦定义了关系,您就可以create your endpoint classes around the JDO model classes。这将创建基本的api方法。您可能希望更改端点类方法以满足您的需要,例如更改操作的创建方式。一个基本的例子是从actions标题创建密钥,如下所示(ActionEnpoint.java):
...
@ApiMethod(name = "insertAction")
public Action insertAction( @Named("title") String title ) {
PersistenceManager pm = getPersistenceManager();
Key key = KeyFactory.createKey(Action.class.getSimpleName(), title);
Action action = null;
try {
action = new Action(key, title);
pm.makePersistent(action);
} finally {
pm.close();
}
return action;
}
...
如果您愿意,可以向UserEndpoint类添加一个方法来查询数据存储区,并使用datastore query objects返回属于该用户和每个日期的所有操作。
您需要向UserEndpoint类添加一个方法,允许您向该用户添加操作,这是一个简单的示例:
...
@ApiMethod(name = "addActionToUser")
public Achiever addActionToUser(
@Named("userId") String userId,
@Named("actionTitle") String actionTitle) {
PersistenceManager pm = getPersistenceManager();
Key userKey = KeyFactory.createKey(User.class.getSimpleName(), userId);
Key actionKey = KeyFactory.createKey(Action.class.getSimpleName(), actionTitle);
User user = null;
try {
user = (User) pm.getObjectById(User.class, userKey);
user.addAction(actionKey);
pm.makePersistent(user);
} catch (Exception e) {
}
return user;
}
...
完成上述所有操作后,您可以通过调用UserEndpoint类中的getUser方法轻松获取每个用户的操作列表,该类返回User对象。然后,您可以调用[ReturnedUserObject] .getActions()。现在,新的关注者可以通过调用api方法来获取“跟随者”对象并获取他/她的行为来查看所有“跟随者”操作。然后,您可以按日期对行动进行排序,或者您想象它。
我希望我能正确理解你的问题,我不确定你提到的第一个组件,但似乎你的关系混乱了。我希望这个解决方案至少能指出你正确的方向:)。
如果您需要任何其他帮助或澄清,或者我的回答完全不符合您的要求,请告知我们。
亲切的问候, 三木