Общие друзья Facebook и лимит записи FQL 4999/5000 - PullRequest
9 голосов
/ 26 ноября 2010

Я пытаюсь выбрать все общие друзья с помощью PHP / FQL. Используя мой UID (540 друзей), что означает> 12 000 соединений, из которых> 6500 являются уникальными. Таким образом, этот код должен возвращать все соединения, но Facebook, по-видимому, имеет ограничение на 4999/5000 строк для запросов FQL.

// 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);

Ответы [ 7 ]

7 голосов
/ 28 ноября 2010

Итак, я выкладываю ответ на свой оригинальный вопрос.Я смог обойти ограничение в 5000 строк в запросах FQL, разбив массив UID (используя PHP-функцию array_chunk () с соответствующим именем) и перебрав порции для выполнения мини-запросов, а затем добавив их обратно в один массив,Весь сценарий составляет в среднем 14 секунд для более чем 12 000 строк, что является огромным улучшением.Вы можете увидеть приложение на работе здесь: givememydata.com

О, и Facebook должен пересмотреть свой (пока недокументированный) лимит строк FQL.Что больше облагается налогом на их серверах?Один запрос, который выполняется за 5 секунд или 500 запросов, которые занимают 180 секунд?Извините, пришлось излить.; -)

5 голосов
/ 09 июля 2012
$mutual_friends = $facebook->api('/me/mutualfriends/friendid');
1 голос
/ 03 февраля 2012

Интересное наблюдение: когда я пытаюсь найти всех людей, у которых есть общие друзья, я использую следующий запрос

ВЫБРАТЬ uid1, uid2 ОТ друга ГДЕ uid1 IN (ВЫБРАТЬ uid2 ОТ друга ГДЕ uid1 = $ uid)

Как видите, он очень похож на ваш запрос, за исключением того, что я удалил предложение AND.

Я получаю следующее сообщение об ошибке: «Не удается найти всех друзей 208733.Может только искать вошедшего в систему пользователя или вошедших в него друзей, которые являются пользователями вашего приложения ".

Я думаю, Facebook достаточно умен, чтобы понять, что я пытаюсь сделать что-то, что ему не нужномне делать.Это каким-то образом обнаруживает тот факт, что вы пытаетесь найти только друзей своего друга, которые также являются вашими друзьями, в то время как я пытаюсь найти всех друзей моего друга.

1 голос
/ 26 ноября 2010

Альтернативой может быть использование метода fql.multiquery и создание отдельного запроса FQL для каждого друга (или группы друзей на запрос FQL), но все равно отправка всех запросов в одном запросе..

0 голосов
/ 11 июля 2012

Я делал то же самое - но получал посты на fb-страницах - и столкнулся с забавным кешированием на серверах FB, когда разбил его множественными запросами - кстати, пакетирование FQL - способ обойти это.И да, столкнулся с лимитом 5К и просто дозировал под 5К, и ему пришлось настроить нумерацию страниц, что было болью.

0 голосов
/ 21 марта 2012

Один прием, который я смог использовать, заключается в ограничении количества запросов на основе одного из индексируемых столбцов из ваших таблиц (используя strpos (имя_ столбца, символ / число)).

например:

$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.

0 голосов
/ 26 ноября 2010

FQL поддерживает LIMIT, как обычный SQL. Вы можете попробовать это. http://developers.facebook.com/docs/guides/performance

В противном случае я предлагаю получить идентификаторы друзей для каждого пользователя, сохранить их в таблице SQL, а затем выполнить собственное объединение для получения кроссовера. Вы можете просто получить списки друзей один раз, а затем подписаться на обновления в реальном времени, чтобы поддерживать свои списки в актуальном состоянии. http://developers.facebook.com/docs/api/realtime

...