Я пытаюсь выбрать все подключения общих друзей с 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);
Итак, я отправляю ответ на свой первоначальный вопрос. Мне удалось обойти ограничение 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), но при этом все запросы отправляются в одном запросе.
Интересное замечание: когда я пытаюсь найти всех людей, у которых есть общие друзья, мне нужен следующий запрос
SELECT uid1, uid2 FROM friend WHERE uid1 IN (SELECT uid2 FROM friend WHERE uid1 = $ uid)
Как вы можете видеть, это очень похоже на ваш запрос, за исключением того, что я удалил предложение AND.
Я получаю следующее сообщение об ошибке: «Не удается найти всех друзей 208733. Можете только искать для зарегистрированных пользователей или зарегистрированных пользователей, которые являются пользователями вашего приложения».
Я думаю, что facebook достаточно умен, чтобы понять, что я пытаюсь сделать то, что он не хочет, чтобы я делал. Это как-то обнаруживает тот факт, что вы пытаетесь найти друзей своего друга, которые также являются вашими друзьями, в то время как я пытаюсь найти всех друзей моего друга.
FQL поддерживает LIMIT, как обычный SQL. Вы можете попробовать это. http://developers.facebook.com/docs/guides/performance
В противном случае я предлагаю получить идентификаторы друзей для каждого пользователя, сохраняя их в таблице SQL, а затем выполнить свое собственное соединение, чтобы получить кроссовер. Вы можете просто получить списки друзей один раз, а затем подписаться на обновления в реальном времени, чтобы обновлять списки. http://developers.facebook.com/docs/api/realtime
Один трюк, который, как мне кажется, я смог использовать, – ограничить количество запросов на основе одного из индексируемых столбцов из ваших таблиц (с использованием 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.
Я делал что-то подобное, но получал сообщения на странице fb, и столкнулся с забавным кешированием на серверах FB, когда я избивал его с помощью многокомпонентных продуктов – пакетный FQL – это способ обойти это, кстати. И да, побежал в предел 5K и просто собрался под 5k и должен был настроить разбивку на страницы, что было больно.