2012-04-05 48 views
1

我訪問了Facebook Graph API以獲取代表我的訂閱源(我的Facebook牆)上的最新帖子的JSON對象。然後,我使用PHP Mongo Driver將它保存到一個名爲feeds的MongoDB集合中。使用PHP驅動程序深入查詢MongoDB子集兩級深入使用PHP驅動程序

//$post['feed']['data'] contains the Facebook JSON object of wall posts 
//create a mongo instance 
$mongo = new Mongo(); 
//access the feeds collection 
$feeds = $mongo->changeup->feeds; 
//dump the feed right into mongo 
$feeds->insert($post['feed']['data']); 

這是在讀回被放入mongo中的整個對象之後,其中一個數組看起來像。

我只向你展示一個,但它給了我多個,每個索引,下一個是[1] => Array()等等...一些結構不同,因爲一些包含[故事]字段,其他字段包含[消息]字段,有些字段包含兩者。

Query: 
$cursor = $feeds->find(); 

foreach ($cursor as $feed) { 
print_r($feed); 
} 

Result: 
[0] => Array 
     (
      [id] => 505212695_10150696450097696 
      [from] => Array 
       (
        [name] => John Doe 
        [id] => 505212695 
       ) 

      [story] => "Text of a story I posted on my wall..." 
      [story_tags] => Array 
       (
        [38] => Array 
         (
          [0] => Array 
           (
            [id] => 15212444 
            [name] => John Doe 
            [offset] => 38 
            [length] => 10 
            [type] => user 
           ) 

         ) 

       ) 

      [type] => status 
      [application] => Array 
       (
        [name] => Share_bookmarklet 
        [id] => 5085647995 
       ) 

      [created_time] => 2012-04-04T05:51:21+0000 
      [updated_time] => 2012-04-04T05:51:21+0000 
      [comments] => Array 
       (
        [count] => 0 
       ) 

) 

的問題是,我不想隨便找整個集合,我想找到只有那些說[消息]這些陣列和[故事]字段,然後隨便找個它們的內容並沒有什麼其他。

我想接受一個子集,兩層深:

//this works, however, I'm only able to get the 0 array 
$cursor = $feeds->find(array(), array('0.story' => true)); 

如何通過所有陣列過濾器?

我希望我的最終結果是這樣的:

Array 
(
    [_id] => MongoId Object 
     (
      [$id] => 4f7db4dd6434e64959000000 
     ) 

    [0] => Array 
     (
      [story] => "Text of a story I posted on my wall..." 
     ) 
    [1] => Array 
     (
      [story] => "Text of a story I posted on my wall..." 
     ) 
    [2] => Array 
     (
      [story] => "Text of a story I posted on my wall..." 
      [message] => "In this case message text exists as well..." 
     ) 
    [3] => Array 
     (
      [message] => "Text of a message I posted on my wall..." 
     ) 

    etc... 
) 

回答

2

我相信最初的問題與各供文檔數據結構開始。注意你的對象只是一個id,然後是一個遞增的數字鍵,這就是它。最理想的是你在頂層插入一個帶有鍵和值的實際對象結構。目前,因爲您直接將facebook數據直接轉儲到mongo中而不進行格式化,驅動程序將您的數組映射到鍵/值。現在每個Feed文檔都有不定數量的匿名對象。

請參閱本:http://www.php.net/manual/en/mongo.writes.php

我會想你的飼料文檔看起來應該會是這樣的:

{ 
    "_id" : ObjectId("4f7db4dd6434e64959000000"), 
    "posts" : 
    [ 
     { 
      "story" : "Text of a story I posted on my wall...", 
      "message" : "In this case message text exists as well...", 
     }, 
     { 
      "story" : "Text of a story I posted on my wall...", 
      "message" : "In this case message text exists as well...", 
     } 
    ], 
    "posts_meta1": "some val", 
    "posts_meta2": "other data" 
} 

注意,它包含了「上崗」頂級鍵,用你的陣列發佈下面的對象。這解決了多個問題。您可以使用頂級關鍵字進行索引,而不是「數字」,您可以擁有更清潔的根級別來添加更多的Feed字段,並且可以乾淨地實現查找查詢。

一個簡單的查找可能是這樣的:

// Return all feed docs, and only include the posts.story field 
db.feeds.find({}, {"posts.story": 1}) 

更先進的查詢可能是這樣的:

// Return an feed document that either contains a posts.story 
// field, or, contains a posts.message field 
db.feeds.find({ 
    $or: [ 
     {$exists: {"posts.story": true}}, 
     {$exists: {"posts.message": true} 
    ] 
}) 

簡而言之,從Facebook返回的數據應該首先被格式化成對象結構,然後插入到mongo中。例如,日期應該插入爲適當的日期對象,而不是原始字符串:http://www.php.net/manual/en/class.mongodate.php。這可以讓你在mongo中進行基於日期的查詢,並且php驅動程序還會確保來回轉換它們,以便它們更適合你的語言。

+0

非常感謝,作品! – Allen 2012-04-05 23:24:58

1

沒有看到Facebook發送的JSON數據,很難說出story_tags字段中的結構應該是什麼樣子。您可能需要從Facebook和力json_decode來轉換成PHP關聯數組的JSON解碼:

$ar = json_decode($post['feed']['data'], true); 

「真」這裏的標誌迫使它處理數據作爲關聯數組。

然後你會插入如下:

$feeds->insert($ar); 

無論哪種方式,我傾向於將數據重組的東西,將其存儲在數據庫之前適合您的需求更好 - 這將讓你除其他事項外,更有效地使用索引。如果您真的需要存儲來自Facebook的整個響應,您可以始終將其存儲爲嵌套對象:

$ar['raw'] = $post['feed']['data']; 
相關問題