2012-04-05 1 views
1

J'ai accédé à l'API Facebook Graph pour obtenir un objet JSON représentant les derniers messages de mon flux (mon mur Facebook). Je l'ai ensuite sauvegardé dans une collection MongoDB appelée feeds en utilisant le pilote PHP Mongo.Interrogation du sous-ensemble MongoDB Deux niveaux profonds avec le pilote 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']); 

C'est ce que l'un des tableaux ressemble à la lecture de retour tout l'objet qui a été placé dans mongo. Je ne vous en montre qu'un seul, mais il me donne plusieurs autres, chacun indexé, le suivant est [1] => Array() et ainsi de suite ... certains sont structurés différemment, car certains contiennent le [ histoire], d'autres contiennent le champ [message], et certains contiennent les deux.

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 
       ) 

) 

Le problème est que je ne veux pas trouver juste la collection, je veux trouver que les tableaux qui ont dit [message] et [histoire] champs, puis trouver tout leur contenu et rien autre.

Je suis en train de recevoir un sous-ensemble, deux niveaux de profondeur:

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

Comment filtrer tous les tableaux?

Je veux que mon résultat final ressemble à ceci:

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... 
) 

Répondre

2

je crois que la question initiale commence par votre structure de données pour chaque document d'alimentation. Notez que votre objet est simplement un identifiant, puis une quantité croissante de touches numériques, et c'est tout. Ce qui serait idéal est que vous insériez une structure d'objet réelle, avec des clés et des valeurs, au niveau supérieur. Actuellement, parce que vous avez directement déversé les données Facebook directement dans mongo sans le formater, le pilote mappé votre tableau à la clé/valeur. Maintenant, chaque document de flux a un nombre variable d'objets anonymes.

Référez à ceci: http://www.php.net/manual/en/mongo.writes.php

Ce que je pense que votre doc d'alimentation devrait ressembler pourrait être ceci:

{ 
    "_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" 
} 

Notez qu'il contient une clé de niveau supérieur « messages », avec votre tableau de poster des objets en dessous. Cela corrige plusieurs problèmes. Vous avez une clé de niveau supérieur à indexer, au lieu de "nombre", vous avez un niveau racine plus propre pour ajouter plus de champs de flux, et vous pouvez effectuer votre requête de recherche proprement.

Une trouvaille simple pourrait ressembler à ceci:

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

Une requête plus avancée pourrait ressembler à ceci:

// 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} 
    ] 
}) 

En bref, vos données sont revenus de Facebook devraient être d'abord le formater dans un structure de l'objet, puis inséré dans mongo. Par exemple, les dates doivent être insérées comme objets de date appropriés par opposition aux chaînes brutes: http://www.php.net/manual/en/class.mongodate.php. Cela vous permet de faire ensuite des requêtes basées sur des dates dans mongo, et le pilote php s'assurera également de les convertir d'avant en arrière afin qu'elles soient plus natives dans votre langue.

+0

Merci beaucoup, ça marche! – Allen

1

Sans voir les données JSON envoyées depuis Facebook, il est difficile de dire à quoi la structure devrait ressembler dans le champ story_tags.Vous devrez peut-être décoder le JSON provenant de Facebook et json_decode de force pour convertir en un tableau associatif PHP:

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

Le drapeau vrai «forces ici pour gérer les données comme un tableau associatif.

Vous souhaitez ensuite insérer comme suit:

$feeds->insert($ar); 

De toute façon, je serais enclin à restructurer les données à quelque chose qui convient mieux à vos besoins avant de le ranger dans la base de données - cela vous permettra de utiliser les indices plus efficacement entre autres. Si vous avez vraiment besoin de stocker toute la réponse de Facebook, vous pouvez toujours le stocker comme un objet imbriqué:

$ar['raw'] = $post['feed']['data']; 
Questions connexes