0

Java の Google App Engine で Facebook アプリを作成しています。ユーザー (新旧) が私のアプリにアクセスするたびに、Facebook のユーザーの友人の現在のリストがデータストアに正確に保持されていることを確認する必要があります。Facebook Javascript API (FB.api) から友達の最新リストを取得し、データストアで以前に作成/更新されたリストを持っています。データストア内のリストを同期するには、次の 2 つの方法を考えています。

  1. データストア内のユーザーの友達のリスト全体を削除し、すべての友達を (FB Javascript API からのリストに従って) 新たに挿入します。
  2. 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);
}
4

1 に答える 1

0
  1. 計算コストが低くなります。ただし、データストアのコストが高くなります。データストアの操作は比較的遅いため、計算コストは​​低くなりますが、RPC の待機に多くの時間を費やす可能性があることに注意してください。非同期データストア操作を使用していない場合、これは遅くなる可能性があります。

  2. 計算コストは​​高くなりますが、データストアのコストは低くなります。

于 2013-06-27T16:40:00.343 に答える