1

From the below FQL query I'm able to get the actor_id and attachment data for a post that is on my newsfeed and contains 'www.youtube.com'. However, I'd like to be able to also get that user's picture and name. How would I incorporate this into the below query?

SELECT created_time, post_id, actor_id, type, updated_time, attachment
FROM stream 
WHERE post_id IN 
   (SELECT post_id
    FROM stream
    WHERE ('video') IN attachment 
    AND source_id IN
       (SELECT uid2
        FROM friend
        WHERE uid1=me())
    LIMIT 100)

Edit:

    #right fql query, but prints only part of it
    posts_query = "SELECT created_time, post_id, actor_id, type, updated_time, attachment FROM stream WHERE post_id in (select post_id from stream where ('video') in attachment AND source_id IN ( SELECT uid2 FROM friend WHERE uid1=me()) limit 100)"
    fql_var = "https://api.facebook.com/method/fql.query?access_token=" + token['access_token'] + "&query=" + posts_query + "&format=json"
    data = urllib.urlopen(fql_var)
    fb_stream = json.loads(data.read())
    #print ast.literal_eval(json.dumps(fb_stream))

    users_query = "SELECT uid, first_name FROM user WHERE uid IN (SELECT actor_id FROM (" + posts_query+"))"
    fqlquery_user = "https://api.facebook.com/method/fql.query?access_token=" + token['access_token'] + "&query=" + users_query + "&format=json"
    user_data2 = urllib.urlopen(fqlquery_user)
    user_stream2 = json.loads(user_data2.read())
    print ast.literal_eval(json.dumps(user_stream2))
sharataka
  • 5,014
  • 20
  • 65
  • 125

2 Answers2

1

You need to use FQL Multiquery so that you would have two queries - your own to fetch "posts" and the other to fetch "actors". The queries are executed together and you have to adjust your code to pair the two arrays that are returned using values of actor_id.

"posts":"your_query_here"
"actors":"SELECT name,pic_square FROM user WHERE uid IN (SELECT actor_id FROM #posts)"

You can see the results of this query here

Master Drools
  • 728
  • 6
  • 18
1

It seems you can't do it with only one query, because:

  1. You can only SELECT from one table at once in FQL.
  2. There are no JOINs in FQL. (See this question and that one)

If you could, this is how it would look like:

SELECT created_time, post_id, actor_id, type, updated_time, attachment, user.first_name
FROM stream
WHERE ('video') in attachment AND 
        source_id IN (SELECT uid2 FROM friend WHERE uid1=me())
LEFT JOIN user ON user.uid=actor_id
LIMIT 100

But there are no joins, so you need to use what Facebook calls a multiquery, and you would have two queries:

posts_query =
SELECT created_time, post_id, actor_id, type, updated_time, attachment
FROM stream
WHERE ('video') in attachment AND 
        source_id IN (SELECT uid2 FROM friend WHERE uid1=me())
LIMIT 100

users_query =
SELECT uid, first_name
FROM user
WHERE uid IN (SELECT actor_id FROM #posts_query)

Here is a link to the Explorer for you to test it.

Note: There is something useless you are doing in your original query, which is selecting from a table, and adding a subquery in the where clause from that same table. So that's redundant.

Update:

#right fql query, but prints only part of it
posts_query = "SELECT created_time, post_id, actor_id, type, updated_time, attachment FROM stream WHERE post_id in (select post_id from stream where ('video') in attachment AND source_id IN ( SELECT uid2 FROM friend WHERE uid1=me()) limit 100)"
users_query = "SELECT uid, first_name FROM user WHERE uid IN (SELECT actor_id FROM (#posts_query))"

queries = {'posts_query': posts_query, 'users_query': users_query}
fql_var = "https://api.facebook.com/method/fql.query?access_token=" + token['access_token'] + "&q=" + json.dumps(queries_json) + "&format=json"
data = urllib.urlopen(fql_var)
fb_stream = json.loads(data.read())
print ast.literal_eval(json.dumps(fb_stream))

The idea is to send both queries with their names as keys, encode in JSON, so that Facebook understands that #posts_query is the one you sent in that same API request. You to send the name exactly as you send it in the JSON encoded object literally, not replace it by the query itself. Check the docs on multiquery for details and examples.

Community
  • 1
  • 1
jadkik94
  • 7,000
  • 2
  • 30
  • 39
  • Thanks, this makes sense. How would I incorporate this into python? Ive tried the above (in the edit) but isn't seem to be working. – sharataka Dec 07 '12 at 01:10
  • To use these, you need to send them in one shot, i.e. one `urllib` request, because they depend on each other. I'll update my answer to show you how. – jadkik94 Dec 07 '12 at 19:05