Вопрос

Я пытаюсь выбрать все соединения взаимных друзей с 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 и пришлось настроить пагинацию, что было болью.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top