Мне нужно получить все комментарии к странице вентилятора. Не только со стены, но и из альбомов, фотографий, заметок и т. Д.Как получить все комментарии к странице вентилятора
Я решил эту проблему таким образом. Сначала я получаю все объекты (альбомы, заметки и т. Д.) На странице вентилятора. Во-вторых, я получаю commets для каждого объекта, используя многопроцессорный запрос FQL.
// Import comment list
$facebook = \Yii::app()->facebook->setUserAccessToken();
$commentsColumns = array(
'xid', 'object_id', 'post_id', 'fromid', 'time', 'text', 'username',
'reply_xid', 'post_fbid', 'app_id', 'likes', 'comments', 'user_likes',
'is_private', 'id',
);
$offset = 0;
$limit = 30;
while (($offset <= count($objectIdList)) && ($offset <= count($postIdList))) {
$currentObjectIdList = array_slice($objectIdList, $offset, $limit);
$currentPostIdList = array_slice($postIdList, $offset, $limit);
$multiQuery = array(
'comments' =>
' SELECT '.implode(', ', $commentsColumns).' '.
' FROM comment '.
' WHERE ((object_id IN ('.implode(',', $currentObjectIdList).')) '.
' OR (post_id IN ('.implode(',', $currentPostIdList).'))) '.
' AND (time >= ' . $lastCommentTime . ') ' .
' ORDER BY time DESC '.
' LIMIT 1000 ',
'users' =>
' SELECT uid, name ' .
' FROM user ' .
' WHERE uid IN (SELECT fromid FROM #comments) ',
'pages' =>
' SELECT page_id, name ' .
' FROM page ' .
' WHERE page_id IN (SELECT fromid FROM #comments) '
);
$multiQueryResult = $facebook->api(array(
'method' => 'fql.multiquery',
'queries' => $multiQuery
));
// Parse multi query results
$from = array();
foreach ($multiQueryResult as $result) {
switch ($result['name']) {
case 'comments':
$commentList = $result['fql_result_set'];
break;
case 'users':
case 'pages':
foreach ($result['fql_result_set'] as $set) {
switch ($result['name']) {
case 'users':
$from[$set['uid']] = $set['name'];
break;
case 'pages':
$from[$set['page_id']] = $set['name'];
break;
}
}
break;
}
}
// Save comments to local DB
foreach ($commentList as $commentData) {
$comment = new Comment();
$comment->fbId = $commentData['id'];
$comment->fbPageId = $this->fbId;
$comment->from = array(
'id' => $commentData['fromid'],
'name' => isset($from[$commentData['fromid']]) ? $from[$commentData['fromid']] : null,
);
$comment->message = $commentData['text'];
$comment->created_time = $commentData['time'];
$comment->likes = $commentData['likes'];
$comment->save();
}
// Next step
$offset = $offset + $limit;
}
Это решение работает, но не очень быстро. Кто-нибудь знает лучшее решение?
Что на самом деле замедляет его, поиск FQL с несколькими запросами или поиск объектов? Вы получаете идентификаторы объектов с помощью [Batch Requests] (http://developers.facebook.com/docs/reference/api/batch/)? –
Получение идентификаторов объектов довольно быстро (благодаря пакетным запросам). Но запрос FQL слишком медленный. Может быть, потому, что он выполняется для более чем 100 объектов и более 200 сообщений. – Oleg
Вы, вероятно, правы, Facebook нужно получить данные из слишком большого количества источников, которые медленны. Я видел много простых SQL-запросов, которые замедлялись, как черт. Возможно, вы можете ускорить его, разделив эту задачу на несколько запросов, которые могут выполняться параллельно ... –