0

我正在用 Java 在 Google App Engine 上构建 Facebook 应用程序。每次用户(旧的或新的)访问我的应用程序时,我都需要确保 Facebook 中用户的当前好友列表准确地保存在我的数据存储中。我从 Facebook Javascript API (FB.api) 获得了最新的朋友列表,并且我在数据存储区中有一个先前创建/更新的列表。我有两种方法可以同步数据存储中的列表:

  1. 删除数据存储区中用户的整个朋友列表并重新插入所有朋友(根据来自 FB Javascript API 的列表)。
  2. 将我从 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);
}
4

1 回答 1

0
  1. 计算成本更低。但是,它会在数据存储上花费更多。请注意,数据存储操作相对较慢,因此即使计算成本较低,您也可能会花费大量时间等待 RPC。如果您不使用异步数据存储操作,这可能会更慢。

  2. 计算成本更高,但在数据存储上的成本会更低。

于 2013-06-27T16:40:00.343 回答