Facebook 共同好友及 FQL 4999/5000 条记录限制

发布于 2024-10-05 01:16:31 字数 1293 浏览 4 评论 0原文

我正在尝试选择所有共同朋友与 PHP/FQL 的联系。使用我的 UID(540 个朋友),这意味着 >12,000 个连接,其中 >6500 个是唯一的。因此,此代码应该返回所有连接,但 Facebook 显然对 FQL 查询有 4999/5000 行限制。

// select mutual unique friends
 $unique_connections = $facebook->api_client->fql_query("

  SELECT uid1, uid2 FROM friend 
   WHERE uid1 IN 
   (SELECT uid2 FROM friend WHERE uid1=$uid)
   AND uid2 IN 
   (SELECT uid2 FROM friend WHERE uid1=$uid)
 ");

我知道上面的数字,因为我编写的原始代码循环遍历我的朋友列表,并为每个人发送一个 getMutualFriend 查询。

foreach ($friends as $key) 
{
    $mutual_friends = $facebook->api_client->friends_getMutualFriends($key);
    foreach ($mutual_friends as $f_uid)
    {
        array_push($all_connections, array($key,$f_uid)); 
    }
}

当然,运行该脚本大约需要 3 分钟,而 FQL 查询会在 5 秒内返回。经过一个小时的寻找这个答案后,我得出的结论是,解决这个问题的唯一方法是混合使用这两种方法。好吧,然后在这里发帖。关于编写此脚本并打破 4999/5000 行限制的更好方法有什么想法吗?

这是一个 fql_multiquery ,它应该执行与上面相同的操作。也仅限于 4999/5000。

$queries = '{
"user_friends":"SELECT uid2 FROM friend WHERE uid1 = '.$uid.'",
"mutual_friends":"SELECT uid1, uid2 FROM friend WHERE uid1 IN (SELECT uid2 FROM #user_friends) AND uid2 IN (SELECT uid2 FROM #user_friends)"
}';

$mq_test = $facebook->api_client->fql_multiquery(trim($queries));
print_r($mq_test);

I'm trying to select all mutual friends' connections with PHP/FQL. Using my UID (540 friends), which means >12,000 connections, of which >6500 are unique. So this code should return all the connections but Facebook apparently has a 4999/5000 row limit on FQL queries.

// select mutual unique friends
 $unique_connections = $facebook->api_client->fql_query("

  SELECT uid1, uid2 FROM friend 
   WHERE uid1 IN 
   (SELECT uid2 FROM friend WHERE uid1=$uid)
   AND uid2 IN 
   (SELECT uid2 FROM friend WHERE uid1=$uid)
 ");

I know the numbers above because the original code I wrote loops through my friend list and sends a getMutualFriend query for each of them.

foreach ($friends as $key) 
{
    $mutual_friends = $facebook->api_client->friends_getMutualFriends($key);
    foreach ($mutual_friends as $f_uid)
    {
        array_push($all_connections, array($key,$f_uid)); 
    }
}

Of course it takes almost 3 minutes to run that script, while the FQL query returns in 5 seconds. After an hour of searching for this answer I've come to the conclusion the only way to get around this is to use a mixture of the two methods. Well that, and post here. Any ideas on a better way to write this script and beat the 4999/5000 row limit?

Here's an fql_multiquery that should do the same as above. It is also limited to 4999/5000.

$queries = '{
"user_friends":"SELECT uid2 FROM friend WHERE uid1 = '.$uid.'",
"mutual_friends":"SELECT uid1, uid2 FROM friend WHERE uid1 IN (SELECT uid2 FROM #user_friends) AND uid2 IN (SELECT uid2 FROM #user_friends)"
}';

$mq_test = $facebook->api_client->fql_multiquery(trim($queries));
print_r($mq_test);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

盗梦空间 2024-10-12 01:16:31

所以,我发布了我原来问题的答案。我能够通过对 UID 数组进行分块(使用适当命名的 array_chunk() PHP 函数)并循环遍历这些块来执行小型查询,然后将其全部附加回一个数组,从而绕过 FQL 查询的 5000 行限制。对于 12,000 多行,整个脚本平均需要 14 秒,因此这是一个巨大的改进。您可以在此处查看该应用程序的工作情况:givememydata.com

哦,Facebook 应该重新考虑他们的(尚未记录的)FQL 行限制。什么对他们的服务器负担更大?单个查询需要 5 秒执行,还是 500 个查询需要 180 秒执行?抱歉,不得不发泄一下。 ;-)

So, I'm posting the answer to my original question. I was able to circumvent the 5000 row limit on FQL queries by chunking the array of UIDs (using the appropriately-named array_chunk() PHP function) and looping through the chunks to execute mini-queries, and then appending it all back into one array. The whole script averages 14 seconds for over 12,000 rows so that is a huge improvement. You can see the application at work here: givememydata.com

Oh, and Facebook should reconsider their (still undocumented) FQL row limit. What is more taxing on their servers? A single query that executes in 5 seconds or 500 queries that take 180 seconds? Sorry, had to vent. ;-)

淡淡の花香 2024-10-12 01:16:31
$mutual_friends = $facebook->api('/me/mutualfriends/friendid');
$mutual_friends = $facebook->api('/me/mutualfriends/friendid');
寄离 2024-10-12 01:16:31

另一种方法是使用 fql.multiquery 方法,并构建一个为每个朋友(或每个 FQL 查询一组朋友)单独的 FQL 查询,但仍然在同一请求中发送所有查询。

An alternative would be to use the fql.multiquery method, and build a seperate FQL query for each friend (or a group of friends per FQL query), but still sending all queries in the same request.

一直在等你来 2024-10-12 01:16:31

一个有趣的观察:当我尝试查找所有有共同朋友的人时,我使用以下查询

SELECT uid1, uid2 FROMfriend WHERE uid1 IN (SELECT uid2 FROMfriend WHERE uid1=$uid)

如您所见,它非常相似到你的查询,除了我删除了 AND 子句。

我收到以下错误消息:“无法查找 208733 的所有朋友。只能查找已登录的用户或已登录用户的朋友是您的应用程序的用户”。

我想 Facebook 足够聪明,能够发现我正在尝试做一些它不希望我做的事情。它以某种方式检测到这样一个事实:您试图只找到您朋友的朋友,同时也是您的朋友,而我试图找到我朋友的所有朋友。

An interesting observation: When I try to find all the people that have mutual friends me I user the following query

SELECT uid1, uid2 FROM friend WHERE uid1 IN (SELECT uid2 FROM friend WHERE uid1=$uid)

As you can see it is very similar to your query, except that I removed the AND clause.

I get the following error message: "Can't lookup all friends of 208733. Can only lookup for the logged in user or the logged in user's friends that are users of your app".

I guess facebook is smart enough to figure out that I am trying to do something that it doesn't want me to do. It somehow detects the fact that you are trying to find only your friend's friends that are also your friends, while I am trying to find all of my friend's friends.

浮世清欢 2024-10-12 01:16:31

FQL 支持 LIMIT,就像常规 SQL 一样。你可以尝试一下。
http://developers.facebook.com/docs/guides/performance

否则,我建议获取每个用户的朋友 ID,将其存储在 SQL 表中,然后执行您自己的联接以获得交叉。您也许只需获取一次好友列表,然后订阅实时更新即可使您的列表保持最新状态。
http://developers.facebook.com/docs/api/realtime

FQL supports a LIMIT, just like regular SQL. You may try that.
http://developers.facebook.com/docs/guides/performance

Otherwise, I suggest getting the friend IDs for each user, storing those in a SQL table, then performing your own join to get the crossover. You may be able to just get the friends lists once and then subscribe to realtime updates to keep your lists up to date.
http://developers.facebook.com/docs/api/realtime

遥远的绿洲 2024-10-12 01:16:31

我似乎能够使用的一个技巧是根据表中的可索引列之一来限制查询数量(使用 strpos(column_name, character / number))。

例如:

$fql = "SELECT pid,src_big,owner FROM photo WHERE album_object_id IN 
      (SELECT object_id FROM privacy WHERE 
             ( object_id IN ( SELECT object_id FROM album WHERE owner IN (SELECT uid2 FROM friend WHERE 
                   ( uid1 = " . $this->nextUser->fbid . " AND **strpos(uid2,2) = 1**  )))                                   
           AND ( value = 'FRIENDS_OF_FRIENDS' OR value = 'EVERYONE'  ) )) ;

这样您可以将其拆分为 10 个子查询,或者将字母数字字段拆分为 33 个子查询。

One trick it seems i was able to use is to limit the no of queries based on one of the indexable columns from your tables ( using strpos(column_name, character / number)) .

ex:

$fql = "SELECT pid,src_big,owner FROM photo WHERE album_object_id IN 
      (SELECT object_id FROM privacy WHERE 
             ( object_id IN ( SELECT object_id FROM album WHERE owner IN (SELECT uid2 FROM friend WHERE 
                   ( uid1 = " . $this->nextUser->fbid . " AND **strpos(uid2,2) = 1**  )))                                   
           AND ( value = 'FRIENDS_OF_FRIENDS' OR value = 'EVERYONE'  ) )) ;

And this way you can split it in 10 subqueries, or for a alphnumeric field in 33.

神也荒唐 2024-10-12 01:16:31

我正在做类似的事情 - 但是获取 Facebook 页面帖子 - 当我用多重查询进行攻击时,在 FB 服务器上遇到了有趣的缓存 - 顺便说一句,批处理 FQL 是解决这个问题的一种方法。是的,遇到了 5K 限制,批处理量低于 5K,并且必须设置分页,这很痛苦。

I was doing a similar thing- but getting fb page posts- and ran into funny caching on the FB servers when I pummeled it with multiqueries - batching FQL is a way to get around this, btw. And yeah, ran into the 5K limit and just batched under 5k and had to set up paginating, which was a pain.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文