Java の Google App Engine で Facebook アプリを作成しています。ユーザー (新旧) が私のアプリにアクセスするたびに、Facebook のユーザーの友人の現在のリストがデータストアに正確に保持されていることを確認する必要があります。Facebook Javascript API (FB.api) から友達の最新リストを取得し、データストアで以前に作成/更新されたリストを持っています。データストア内のリストを同期するには、次の 2 つの方法を考えています。
- データストア内のユーザーの友達のリスト全体を削除し、すべての友達を (FB Javascript API からのリストに従って) 新たに挿入します。
- FB から取得した友人のリストと、データストアにある友人のリストを比較します。FB からのリストで新しい友人 (データストアには存在しない) を見つけて、データストアに追加します。次に、データストアのリストには存在するが、FB からのリストには存在しない友人を探します (ユーザーが一部のユーザーを友人から外し、データストアから削除した可能性があります)。
これら 2 つのアプローチのうち、より効率的で、高速で、データストアの読み取り/書き込みコストが低いのはどれですか?
私が2番目のアプローチのために持っているコードの下を見てください:
//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);
}