我正在用 Java 在 Google App Engine 上构建 Facebook 应用程序。每次用户(旧的或新的)访问我的应用程序时,我都需要确保 Facebook 中用户的当前好友列表准确地保存在我的数据存储中。我从 Facebook Javascript API (FB.api) 获得了最新的朋友列表,并且我在数据存储区中有一个先前创建/更新的列表。我有两种方法可以同步数据存储中的列表:
- 删除数据存储区中用户的整个朋友列表并重新插入所有朋友(根据来自 FB Javascript API 的列表)。
- 将我从 FB 获得的朋友列表与我在数据存储中的朋友列表进行比较:从 FB 的列表中找到新朋友(数据存储中不存在)并将他们添加到数据存储中。其次,寻找存在于数据存储列表中但不存在于来自FB的列表中的朋友(用户可能已取消某些用户的好友,然后将其从数据存储中删除。
这两种方法中哪一种更高效、更快、数据存储读/写成本更低?
请参阅下面我对第二种方法的代码:
//Get user's friend list from the datastore
if (!newUser) { //Only old users will have existing friends in the datastore, so no need to do this for new users
List<String> DSfriendsIdList = new ArrayList<String>(); //List for keeping the ids of friends in the datastore
Query DSFLquery = new Query("Friend", userKey); //Datastore Friends List query
List<Entity> DSFriendListEntities = datastore.prepare(DSFLquery).asList(FetchOptions.Builder.withDefaults());
if (!DSFriendListEntities.isEmpty()) {
for (Entity dsfle : DSFriendListEntities) { //Build a Set of id's from the entities from the datastore
DSfriendsIdList.add((String) dsfle.getProperty("id"));
}
Set<String> FBfriendsIdSet = new HashSet<String>(); //Set to hold ids coming from Facebook
Set<Entity> FriendsToBeSaved = new HashSet<Entity>(); //Set to hold new friends that will be added to the datastore
size = new Integer(req.getParameter("size")).intValue(); //Number of friends coming from Facebook who use this app
for (int i=0; i<size; ++i) { //Run through each friend from the list of friends coming from Facebook
String FBfriendId = req.getParameter("friends[" + i + "][id]");
FBfriendsIdSet.add(FBfriendId);
if (!DSfriendsIdList.contains(FBfriendId)) { //If this friend id is of a new friend
Filter frndFilter = new FilterPredicate("id", FilterOperator.EQUAL, FBfriendId);
Query frndUserQuery = new Query("User").setFilter(frndFilter).setKeysOnly(); //...find this friend in the User database
List<Entity> frnd = datastore.prepare(frndUserQuery).asList(FetchOptions.Builder.withDefaults());
Key friendUserKey = null;
if (!frnd.isEmpty()) { // A Friend is added only if he is found in User data
Entity friend = new Entity("Friend", userKey); //userKey: Key of the current user in the User database
friend.setProperty("name", req.getParameter("friends[" + i + "][name]"));
friend.setProperty("id", FBfriendId);
friendUserKey = frnd.get(0).getKey();
friend.setProperty("userKey", KeyFactory.keyToString(friendUserKey));
FriendsToBeSaved.add(friend); //Add user's friend
friend = new Entity("Friend", friendUserKey);
friend.setProperty("name", userName);
friend.setProperty("id", userId);
friend.setProperty("userKey", KeyFactory.keyToString(userKey));
FriendsToBeSaved.add(friend); //Add user as friend's friend
}
}
}
if (!FriendsToBeSaved.isEmpty()) datastore.put(FriendsToBeSaved);
//Remove those friends from the datastore who the user may have unfriended on Facebook
Set<Key> FriendsToBeDeleted = new HashSet<Key>();
int i=0;
for (String DSId : DSfriendsIdList) {
if (!FBfriendsIdSet.contains(DSId)) {
Key k = DSFriendListEntities.get(i).getKey(); //Get the key of user's friend who will be deleted
FriendsToBeDeleted.add(k);
String frndUserKey = (String) DSFriendListEntities.get(i).getProperty("userKey");
Query frndToBeDelquery = new Query("Friend", KeyFactory.stringToKey(frndUserKey));
Filter f = new FilterPredicate("id", FilterOperator.EQUAL, userId); //Get the key of Friend where this user is friend of the friend
List<Entity> frndToBeDelEntities = datastore.prepare(frndToBeDelquery.setFilter(f)).asList(FetchOptions.Builder.withDefaults());
FriendsToBeDeleted.add(frndToBeDelEntities.get(0).getKey());
}
++i;
}
if (!FriendsToBeDeleted.isEmpty()) datastore.delete(FriendsToBeDeleted);
}
} else { //This is a new user, and therefore there are no friends in the datastore of this user
//Just add all the FBFriends of this user in the datastore
Set<Entity> FriendsToBeSaved = new HashSet<Entity>(); //Set to hold new friends that will be added to the datastore
for (int i=0; i<size; ++i) { //Run through each friend from the list of friends coming from Facebook
String FBfriendId = req.getParameter("friends[" + i + "][id]");
Filter frndFilter = new FilterPredicate("id", FilterOperator.EQUAL, FBfriendId);
Query frndUserQuery = new Query("User").setFilter(frndFilter).setKeysOnly(); //Find this friend in the User database
List<Entity> frnd = datastore.prepare(frndUserQuery).asList(FetchOptions.Builder.withDefaults());
Key friendUserKey = null;
if (!frnd.isEmpty()) { // A Friend is added only if he is found in User data
Entity friend = new Entity("Friend", userKey); //userKey: Key of the current user in the User database
friend.setProperty("name", req.getParameter("friends[" + i + "][name]"));
friend.setProperty("id", FBfriendId);
friendUserKey = frnd.get(0).getKey();
friend.setProperty("userKey", KeyFactory.keyToString(friendUserKey));
FriendsToBeSaved.add(friend); //Add user's friend
friend = new Entity("Friend", friendUserKey);
friend.setProperty("name", userName);
friend.setProperty("id", userId);
friend.setProperty("userKey", KeyFactory.keyToString(userKey));
FriendsToBeSaved.add(friend); //Add user as friend's friend
}
}
if (!FriendsToBeSaved.isEmpty()) datastore.put(FriendsToBeSaved);
}