【问题标题】:Querying MongoDB Subset Two Levels Deep Using PHP Driver使用 PHP 驱动程序查询 MongoDB 子集两层深度
【发布时间】:2012-04-05 15:24:47
【问题描述】:

我已访问 Facebook Graph API 以获取一个 JSON 对象,该对象代表我的提要(我的 Facebook 墙)上的最新帖子。然后,我使用 PHP Mongo 驱动程序将其保存到名为 feeds 的 MongoDB 集合中。

//$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() 等等......有些结构不同,因为有些包含 [故事] 字段,其他包含 [message] 字段,有些包含两者。

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
                )

)

问题是我不想只找到整个集合,我只想找到那些有 say [message] 和 [story] ​​字段的数组,然后只找到它们的内容而不是别的。

我正在尝试接收一个子集,两层深:

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

【问题讨论】:

    标签: php json facebook-graph-api mongodb mongodb-php


    【解决方案1】:

    我相信最初的问题是从每个提要文档的数据结构开始的。请注意,您的对象只是一个 id,然后是递增数量的数字键,仅此而已。理想的做法是在顶层插入一个带有键和值的实际对象结构。目前,由于您直接将 facebook 数据直接转储到 mongo 中而不对其进行格式化,因此驱动程序将您的数组映射到键/值。现在每个提要文档都有不同数量的匿名对象。

    参考这个: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"
    }
    

    请注意,它包含一个“posts”顶级键,下面是您的帖子对象数组。这解决了多个问题。你有一个顶级键来索引,而不是“数字”,你有一个更干净的根级别来添加更多的提要字段,你可以干净地实现你的查找查询。

    一个简单的查找可能如下所示:

    // 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 驱动程序还将确保来回转换它们,以便它们更适合您的语言。

    【讨论】:

      【解决方案2】:

      没有看到从 Facebook 发送的 JSON 数据,很难判断 story_tags 字段中的结构应该是什么样子。您可能需要解码来自 Facebook 的 JSON 并强制 json_decode 转换为 PHP 关联数组:

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

      此处的“true”标志强制它将数据作为关联数组处理。

      然后您将插入如下:

      $feeds->insert($ar);
      

      无论哪种方式,在将数据存储到数据库之前,我都倾向于将数据重组为更适合您需求的东西——这将使您能够更有效地使用索引。如果您确实需要存储来自 Facebook 的整个响应,则可以始终将其存储为嵌套对象:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-05-14
        • 1970-01-01
        • 2012-05-15
        • 2012-03-04
        • 2013-01-05
        • 2020-04-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多