【问题标题】:Batching up, sending, and receiving a large number of Facebook Graph API calls批处理、发送和接收大量 Facebook Graph API 调用
【发布时间】:2011-11-17 04:09:39
【问题描述】:

我正在尝试使用 Graph API 和 PHP+JS SDK 来获取一个人的好友列表,然后出去获取好友列表中每个人的共同好友。我可以轻松获得好友列表,因为它只是一个简单的 API 调用。然而,当试图获得所有共同的朋友时,问题就出现了。假设一个人有 500 个朋友,那么一次运行应用程序需要 501 次不同的 API 调用,这实在是太多了。

很好。

下一个想法。批处理所有这些 API 调用并将 501 变为 25。这似乎是个好主意,这就是我所做的。不幸的是,它没有用。这是我的代码:

KK NVM,我已修复(大部分)。它仍然运行得很慢。这是新代码:

$userFriends = $facebook->api('/me/friends', 'GET');
$queries = array();
$mutual_friends = array();

foreach ($userFriends[data] as $v1) {
    $queries[] = array('method' => 'GET', 'relative_url' => '/me/mutualfriends/'.$v1[id]);
    if (count($queries)==20){
        $batchResponse = $facebook->api('?batch='.json_encode($queries), 'POST');
        foreach (range(0,count($queries)-1) as $n) {
            $mutual_friend[] = json_decode($batchResponse[$n]['body'], true);
        }
        $queries = array();
    }
    $batchResponse = $facebook->api('?batch='.json_encode($queries), 'POST');
    foreach (range(0,count($queries)-1) as $n) {
        $mutual_friend[] = json_decode($batchResponse[$n]['body'], true);
    }
}

我偷偷怀疑你不应该像这样批量 API 调用,但我可能是错的。另外,我读到 FQL 实际上是获取此类/大量信息的更好、首选方法,但这意味着我也需要访问其他人的朋友列表。

我能想到的唯一其他解决方案是限制调用,但我真的不想这样做,因为我不希望应用程序运行缓慢或等待时间过长。

我正在尝试做的事情可能吗?我会以错误的方式去做吗?任何输入或专业知识将不胜感激。

【问题讨论】:

标签: php facebook facebook-graph-api facebook-fql facebook-php-sdk


【解决方案1】:

在我看来,FQL 在这方面确实更好。

这样的东西应该可以回答你的问题:

$fql = "SELECT uid1,uid2 FROM friend WHERE uid1 IN ( SELECT uid2 FROM friend WHERE uid1 = me() )";
$friends = $GLOBALS["facebook"]->api(array(
    'method' => 'fql.query',
    'query' => $fql,
));

关于权限,我认为在每种情况下(批处理 API 或 FQL),您都需要用户的权限。

编辑: 事实上,调用过程中有一个异常,实际上是被禁止的:

致命错误:未捕获异常:604:无法查找 XXXXXXXX 的所有朋友。只能查找登录用户 (YYYYYYYYY),或 具有适当权限的登录用户的朋友 在 .../php-sdk-v3.1/src/base_facebook.php 第 1039 行

【讨论】:

    【解决方案2】:

    很抱歉在这里切换语言,但我使用 Koala 让它在 Ruby 中运行良好。我正在使用Batch Request,如下所示:

     friends = @graph_batch.batch do |batch_api|
        batch_api.get_connections("me", "friends", {:limit => 100, :offset => 0}, :batch_args => {:name => "get-friends"})
        batch_api.get_objects("{result=get-friends:$.data.*.id}")
        batch_api.graph_call("method/fql.query", { :query => "SELECT uid1, uid2 FROM friend WHERE uid2 IN ({result=get-friends:$.data.*.id}) AND uid1 IN (SELECT uid2 FROM friend WHERE uid1=me())" }, "post" )
     end
    

    也就是说,

    1. 图表 - 获取我的朋友列表 - /me/friends
    2. 图表 - 获取我的朋友数据 - /?ids={result=get-friends:$.data.*.id}
    3. FQL - 获取所有共同好友 - /method/fql.query?query=SELECT uid1, uid2 FROM friend WHERE uid2 IN ({result=get-friends:$.data.*.id}) AND uid1 IN (SELECT uid2 FROM friend WHERE uid1=me())" } (使用适当的转义和 POST 方法)

    第三个查询将返回一个元素列表,uid1,uid2。从那里,您拥有计算共同朋友数量所需的所有数据。在 Ruby 中,我使用以下代码:

     friends[2].clone.delete_if { |r| r['uid2'] != "xxxxxxx" }.count
    

    基本上,我计算数组中 uid2 是特定 ID 的所有元素。我确信有更好的计数方法,但数据现在是你的了。希望这会有所帮助,再次为您切换语言感到抱歉(但是当您使用 API 时,语言是什么意思?)。

    编辑:您一次只能执行大约 100 行。您可以调整限制/偏移参数以对结果进行分页。

    【讨论】:

    • 这是我最终使用 FQL 所做的,但现在的问题是您最终达到了行限制并且查询不会完全完成。
    • 编辑得更清楚,可以使用limit / offset分页
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-10
    • 2020-12-21
    • 2021-10-21
    相关资源
    最近更新 更多