Фейсбук взаимных друзей и FQL 4999/5000 предел записи
-
28-09-2019 - |
Вопрос
Я пытаюсь выбрать все соединения взаимных друзей с 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)
");
Я знаю цифры выше, потому что оригинальный код, который я написал петли через мой список друзей и отправляет запрос GetMuturefriend для каждого из них.
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);
Решение
Итак, я размещаю ответ на мой оригинальный вопрос. Я смог обойти ограничение на 5000 строк на запросах FQL, путем курения массива UID (с помощью функции PHP соответствующим образом с именем Array_chunk ()) и зацикливается через куски для выполнения мини-запросов, а затем добавления все это обратно в один массив Отказ Весь скрипт в среднем составляет 14 секунд для более 12 000 рядов, так что это огромное улучшение. Вы можете увидеть приложение на работе здесь: givememydata.com.
Ох, и Facebook должен пересмотреть их (все еще недокументированный) предел строки FQL. Что больше налогом на своих серверах? Один запрос, который выполняет за 5 секунд или 500 запросов, которые занимают 180 секунд? Извините, пришлось отказать. ;-)
Другие советы
$mutual_friends = $facebook->api('/me/mutualfriends/friendid');
Альтернатива будет использовать fql.multiquery Способ и построить отдельный запрос FQL для каждого друга (или группы друзей на запрос FQL), но все еще отправляя все запросы в тот же запрос.
Интересное наблюдение: когда я пытаюсь найти всех людей, которые имеют взаимные друзья, я пользователю следующий запрос
Выберите UID1, UID2 от друга, где uid1 in (выберите UID2 от друга, где uid1 = $ uid)
Как вы можете видеть, это очень похоже на ваш запрос, за исключением того, что я удалил и оговорку.
Я получаю следующее сообщение об ошибке: «Не могу найти всех друзей 208733. Могут ли только найти вошли в систему пользователя или зарегистрированные друзья пользователя, которые являются пользователями вашего приложения».
Я думаю, что Facebook достаточно умно, чтобы выяснить, что я пытаюсь сделать то, что он не хочет, чтобы я сделал. Это как-то обнаруживает тот факт, что вы пытаетесь найти только друзья вашего друга, которые также ваши друзья, пока я пытаюсь найти всех друзей моего друга.
FQL поддерживает предел, как обычный SQL. Вы можете попробовать это.http://developers.facebook.com/docs/guide/performance.
В противном случае я предлагаю получать удостоверения личности друзей для каждого пользователя, сохраняя их в таблице SQL, затем выполняя свое собственное соединение, чтобы получить кроссовер. Вы можете просто получить списки друзей один раз, а затем подписаться на обновления в реальном времени, чтобы сохранить ваши списки на сегодняшний день.http://developers.facebook.com/docs/api/realtime
Один трюк, кажется, я смог использовать, это ограничить отсутствие запросов на основе одного из индексируемых столбцов из таблиц (используя strpos (column_name, символ / номер)).
бывший:
$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.
Я делал подобное, но получение сообщений страницы FB - и бежал в смешные кэширование на серверах FB, когда я разбудил его с Multiqueries - Batching FQL - это способ обойти это, кстати. И да, пробежал в предел 5K и просто наносил добью до 5K и пришлось настроить пагинацию, что было болью.