2012-03-27 8 views
14

私はFacebookの管理者のページからいくつかの洞察を得ようとしています。
私のコードは、mySQLを使って作業したいページのIDを取得します。私はその部分を含めなかった。FacebookのFQLのパフォーマンスと使いやすさの向上

これ以降、facebook IDのpage_id、name、fan_countが取得され、fancounts[]に保存されます。

私には2つの問題があります。

  1. それは私がこのようなデータをエコーする方法を見つけることができない、非常に遅いパフォーマンス
  2. があります

私の質問は、コードは、パフォーマンスやショーを向上させるために修飾することができるか、あります上記のデータですか?私はfql.multiqueryについて読んでいます。それはここで使用できますか?

私にコード例を教えてください。ありがとうございます

+0

の代わりに '$を保存しますfancounts'と '$ messages'を配列として使うと、データをエコーアウトするとどうなりますか?それは表示されませんか? – hohner

+0

@Jamieはい、最初のすべての名前、ファン、IDを表示し、すべてのメッセージを表示し続けます。私は以前これが好きだった。 – EnexoOnoma

+0

[facebook batch request](http://developers.facebook.com/docs/reference/api/batch/) –

答えて

5

あなたがnページを持っている場合は、あなたのスクリプトはn+1のクエリを作成します。これはあなたのスクリプトの主な欠点です。これが低いパフォーマンスの理由です。

バッチリクエストを使用してクエリを組み合わせることができます。以下のスクリプトを使用して、必要なものを達成することができます。私はそれらのn+1クエリをたった1つのバッチクエリに結合しました。だからあなたのスクリプトよりも速くマッシュアップするでしょう。

echoの部分も修正しました。これで、あなたの質問に記載されているようにスクリプトに出力が表示されます。

// Get the IDs 
$pages = array(); 
$pagesIds = implode(',', $pages); 

// fancounts[] holds the page_id, name and fan_count of the Ids I work with 
$fancounts = array(); 
$q = "SELECT page_id, name, fan_count FROM page WHERE page_id IN ({$pagesIds})"; 
$queries[] = array('method'=>'GET', 'relative_url' => 'method/fql.query?query=' . urlencode($q)); 

$messages = array(); 
foreach($pages as $id) 
{ 
    $q = "SELECT message FROM stream WHERE source_id = '$id' LIMIT 2"; 
    $queries[] = array('method'=>'GET', 'relative_url' => 'method/fql.query?query=' . urlencode($q)); 
} 

// The batch query 
$batchResponse = $facebook->api('?batch='.json_encode($queries), 'POST'); 
$pagesFanCounts = json_decode($batchResponse[0]['body'], TRUE); 

foreach ($pagesFanCounts as $page) 
{  
    $fancounts[] = number_format($page['page_id'],0,'','')."-".$page['name']."-".$page['fan_count']; 
} 

for($i=0; $i < count($fancounts); $i++) 
{ 
    echo '</br>',$fancounts[$i],'<br>'; 
    $temp = json_decode($batchResponse[$i+1]['body'], TRUE); 
    foreach ($temp as $msg) 
    { 
     echo ($msg['message']); 
     echo "</br>"; 
    } 
} 
12

現時点では、Facebookのデータベースへの2回の個別の呼び出しが行われ、すべての処理が遅くなります。 Facebookはマルチクエリーを提供しているので、できるだけ少数のDBコールですべてを行うことができます。

"query1":"SELECT page_id, name, fan_count FROM page WHERE page_id IN ($pagesIds)" 

そして、彼らはあなたが前にクエリを参照することができますので、あなたは#の後にそれを単に含めることができます:あなたが使用して考えなければならないの呼び出しがある

"query2":"SELECT message FROM stream WHERE source_id IN (SELECT page_id FROM #pages) LIMIT 2" 

あなたが使用する必要がPHP 2番目のクエリが通過していない場合は、ちょうどこのクエリとFB DBのテストを試してみて、それが動作するかどうかを確認

$query = array(
    "pages"=>"SELECT page_id, name, fan_count FROM page WHERE page_id IN ($pagesIds)", 
    "messages"=>"SELECT message FROM stream WHERE source_id IN (SELECT page_id FROM #pages) LIMIT 2" 
); 

$fql_url = $facebook->api(array(
    'method' => 'fql.multiquery', 
    'queries' => $query 
)); 

print_r($fql_url); 

:このようなものです。クエリで何も返されない場合は、アクセス許可(機密テーブルへのアクセス)に問題がある可能性がありますが、これは当てはまりません。私は頻繁に遭遇したもう一つの問題は、FQLは空白で自分自身をトリップ方法ですので、あなたの配列からすべての可能な空白文字を省略してみてください。

$query = array("pages"=>"SELECT page_id, name, fan_count FROM page WHERE page_id IN ($pagesIds)","messages"=>"SELECT message FROM stream WHERE source_id IN (SELECT page_id FROM #pages) LIMIT 2"); 

うわー、それは読みやすいです... これは、FQLでFacebook's documentationから撮影されました、しかし、サードパーティ製のライブラリを使用している場合は、Webアプリケーションに合わせて変更する必要があります。すべてのデータは$fql_urlに保存されます。あなたがする必要があることは、それをループして、必要な情報をエコーアウトすることだけです。含まれているすべての情報の要約を表示する場合は、ベアリングを取得するためにprint_r()またはvar_dump()を使用することを検討してください。あなたはstreamテーブルの権限を持っていないようですので、あなたが2番目のクエリのために空の配列を受け取っている

EDIT

理由があります。あなたがFacebookのdocumentationをチェックすると、彼らはこのテーブルにアクセスするために必要な基準を言及:

To read the stream table you need

  • read_stream permissions for all posts that the current session user is able to view
  • read_insights permissions to see post impressions for any posts made by a Page owned by the current session user

あなたが持っているアクセス許可かどうか確認するには、このクエリを実行することができます

$check_query = $facebook->api(array(
    "method"    => "fql.query", 
    "query"     => "SELECT * FROM permissions WHERE uid=me()" 
)); 

foreach($check_query[0] as $k => $v) { 
    if($v === "1") { 
        echo "<strong>$k</strong> permission is granted.<br>"; 
    } else { 
        echo "<strong>$k</strong> permission is not granted.<br>"; 
    } 
} 
+0

私は同じ答えを投稿しようとしていたので、これを試しましたか?ただし、2番目のクエリは常に空の配列 "[]"を返しました。 –

+0

@Jamie私は変数を修正しました( '_multiquery'を削除しました)、' print_r($ fql_result) 'を試みました。 "、" type ":" OAuthException "、" code ":601}} *パーサーエラー:予期しない '{'位置0で" – EnexoOnoma

+0

@ P.Galbraith上記のSDKなどを使って試しましたか?なぜなら私はエラーを受け取るからです。 – EnexoOnoma

2

高速Webアプリケーションのゴールデンルールを破っているため、コードは高速に実行されません。

request1->(wait for response-> download data) -> request2 (wait for response -> 
download data) -> and so on ...... 

そして、あなたが本当に何をすべきか: あなたが実際に今の書き込みを行うことである -

request1->(wait for response-> download data) 
request2->(wait for response-> download data) 
request3->(wait for response-> download data) 
...... 
...... 

はい、あなたは合計応答時間を短縮するために、一度に複数の要求をしたはずです。ブラウザはこのようにしてページの読み込みを高速化します。

私はRSSフィードフェッチャー(これはRSSリンクの巨大なデータベースを持っています)で働いている間、同様の問題に直面しています。私はあなたに二つのこと

  1. 使用一度に複数のコマンドをフェッチするマルチcurlコマンドを提案することができ、この問題を解決するために

    。一度に複数のリクエストを行うと、全体の時間が短縮されるため、実際にスクリプトをスピードアップします。

  2. ただし、上記の解決策はいくらか拡張されます。多くのデータを照会している場合は、PHPがマルチスレッドをサポートしていないため、別の場所を探す必要があります。代わりにjavaまたはnode.jsを使用して、redisサーバーを使用して(それを過小評価しないでください)、phpスクリプトとjavaまたはnode.js間のパイプラインとしてpub/sub機能を使用することができます。私によれば、それは最善の選択肢であり、私はそれを使って何十万ものレコードを取り出し、それは決して失敗しません。

そして私は本当にあなたがあなたのインターネット接続速度で助けることができない他の事;)

・ホープこれはあなたの問題を解決:)

ディーパック

関連する問題