【问题标题】:Fetching photos in which 2 or more people are tagged获取标记了 2 个或更多人的照片
【发布时间】:2013-05-04 21:41:20
【问题描述】:

正如标题所说,我正在尝试获取最多 10 张照片,其中标记了当前登录的用户和他/她的一个或多个朋友。目前我正在尝试使用 PHP API 和 FQL。

我是 FQL 新手,但对编程等方面并不陌生。我目前能够实现我想要的唯一方法是动态构建多个查询,如下所示:

SELECT pid, src_big FROM photo WHERE pid IN(  
  SELECT pid FROM photo_tag WHERE subject = me() 
) AND pid IN( 
  SELECT pid FROM photo_tag WHERE 
    subject = '1530195' OR 
    subject = '3612831' OR 
    subject = '6912041' OR 
    ...
)

除了丑之外,这很慢。查询被限制在上面显示的长度,因为当它们变得更长时它们会失败。

多查询对我没有帮助,因为我不能使用 'as',但 SQL 不是我最大的优势,我真的希望我错过了什么..

一定有更好的方法!有人吗?

【问题讨论】:

    标签: facebook facebook-fql photo-tagging


    【解决方案1】:

    只需使用两个查询并使用您选择的编程语言进行交集。

    • SELECT subject, pid FROM photo_tag WHERE subject = me()
    • SELECT pid, subject FROM photo_tag WHERE subject IN (SELECT uid2 FROM friend WHERE uid1=me())

    批处理这两个调用

    fql?q={"userphotos":"SELECT subject, pid 
                         FROM photo_tag 
                         WHERE subject = me()",
           "friendphotos":"SELECT pid, subject 
                           FROM photo_tag 
                           WHERE subject IN 
                          (SELECT uid2 FROM friend WHERE uid1=me())"}
    

    然后在你的编程语言中做这两组的交集。

    a0 = data['data'][0]['fql_result_set'] a1 = data['data'][1]['fql_result_set']

    例如在 Python 中,一些简单的东西

    >>> photos = {}
    >>> for p in a0:
    ...     for q in a1:
    ...         if p['pid'] == q['pid']:
    ...             pid =  p['pid']
    ...             if pid in photos:
    ...                 photos[pid].append(p['subject'])
    ...             else:
    ...                 photos[pid] = [q['subject']]
    ...                 photos[pid].append(p['subject'])
    

    photos 将给出一个字典,其中每个键都有一个 id 列表作为值。 只需取其中的 10 个并将其提供给 photo 表 FQL 调用

    在带有 facepy 模块的 Python 中,它可能看起来像

    photoquery = 'SELECT pid, src_big FROM photo WHERE '+
                 'pid ='+pid1+' OR
                 'pid ='+pid2+' OR
                  ...
    
    graph.fql(photoquery)
    

    总体上最慢的部分将是对朋友的 photo_tag 查询。 SELECT pid, subject FROM photo_tag WHERE subject IN (SELECT uid2 FROM friend WHERE uid1=me())

    【讨论】:

    • 谢谢。这几乎可以正常工作,但奇怪的是,当我将SELECT subject, pid FROM photo_tag WHERE subject = me() 作为多重查询的一部分时,它会返回很多我朋友的照片,但不是我。但是当我发出与单个查询完全相同的 FQL 请求时,它会做它应该做的事情,并返回我的照片。与您的其他(非常好的)逻辑相结合的最终结果是,我确实得到了标记有 2 个人的照片,但我不是其中之一..
    • @MikeTimberlake 你能粘贴bin 1)多查询响应中每个数据集的sn-p 2)你的逻辑实现。如果查询没有返回请求的内容,尤其是subject=me,那就太奇怪了
    • see here 我希望这已经足够清楚了吗?也许我做错了多重查询?
    • @MikeTimberlake 这意味着$multi_result[0]['fql_result_set'];实际上是朋友数据集,$multi_result[]['fql_result_set'];` 是用户数据集。通过检查数据集的名称可以轻松验证。 $multi_result[0]['name'];
    • 哎呀,我真的有那么笨吗!? :( 再次感谢您的帮助。我今天无法处理或验证这些内容,但我会在明天报告,祝你好运。
    【解决方案2】:

    不确定这会在多大程度上提高性能。但至少,它可能会使您的查询更具可读性:

    您可以使用熟悉的WHERE IN (...) 语句代替OR xxx OR yyy 格式的用户ID 列表...

    SELECT pid, src_big FROM photo WHERE pid IN( 
      SELECT pid FROM photo_tag WHERE subject = me() 
    ) AND pid IN(
      SELECT pid FROM photo_tag WHERE subject IN(
        '1530195', 
        '3612831',
        '36800240',
        ...
      )
    

    由于多种原因,这类涉及整个用户好友列表的查询往往会出现问题。首先,可能有数百个朋友,因此即使您设法提高一个查询的性能,您也将不得不执行一系列查询来遍历用户的整个朋友列表。其次,在 API 上一个接一个地运行这些类型的密集查询可能会触发您的应用程序的一些限制...

    我唯一能建议你的是让你的用户知道你正在执行一个密集的操作并且“它可能需要一点时间”:P 在你必须执行查询甚至可能放置的场景之后对每个查询进行限制,以免触发 Facebook 方面的某些机制,这些机制可能会限制您对 API 的访问。

    另一个选项(可能需要对您的应用程序流程进行一些更改)不是选择所有用户朋友,而是显示用户朋友列表并让他们决定要扫描哪些朋友以获取共同照片。这也可以让您限制实际的查询数量。

    【讨论】:

    • 感谢您的意见。对我来说非常有价值的是,您已经确认我并没有简单地错过这样做的明显方式,因为我花了很长时间才接受一个价值 1000 亿美元的网站的 API 可能如此薄弱。我展示的代码从未编写过,只是以编程方式创建,我这样编写它是为了使查询尽可能短以避免最大字符串长度问题。看来我可能不得不放弃这个了。虽然我最多只需要10张图片,所以完成后可能会中断,但它仍然太慢,FB可能不喜欢它..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-14
    • 2012-05-05
    相关资源
    最近更新 更多