2016-10-03 2 views
1

Я пытаюсь запросить общедоступный набор данных Reddit Google BigQuery. Моя цель состоит в том, чтобы вычислить сходство subreddits с использованием Jaccards' Index, который определяется по формуле:BigQuery - сложный коррелированный запрос

Jaccards Formula

Мой план заключается в выборе топ-N = 1000 subreddits с точки зрения количества комментариев в августе 2016 г. Тогда вычислить их для получения комбинаций всех субподрядчиков в форме subreddit1, subreddit2.

Затем используйте эти строки комбинаций, чтобы запросить объединение пользователей между subreddit1 и subreddit 2, а также пересечение.

Запрос я до сих пор это:

SELECT 
    subreddit1, 
    subreddit2, 
    (SELECT 
    COUNT(DISTINCT author) 
    FROM `fh-bigquery.reddit_comments.2016_08` 
    WHERE subreddit = subreddit1 
    OR subreddit = subreddit2 
    LIMIT 1 
) as subreddits_union, 

    (
    SELECT 
     COUNT(DISTINCT author) 
    FROM `fh-bigquery.reddit_comments.2016_08` 
    WHERE subreddit = subreddit1 
    AND author IN ( 
     SELECT author 
     FROM `fh-bigquery.reddit_comments.2016_08` 
     WHERE subreddit= subreddit2 
     GROUP BY author 
    ) as subreddits_intersection 

FROM 

(SELECT a.subreddit as subreddit1, b.subreddit as subreddit2 
FROM (
    SELECT subreddit, count(*) as n_comments 
    FROM `fh-bigquery.reddit_comments.2016_08` 
    GROUP BY subreddit 
    ORDER BY n_comments DESC 
    LIMIT 1000 
    ) a 
CROSS JOIN (
    SELECT subreddit, count(*) as n_comments 
    FROM `fh-bigquery.reddit_comments.2016_08` 
    GROUP BY subreddit 
    ORDER BY n_comments DESC 
    LIMIT 1000 
    ) b 
WHERE a.subreddit < b.subreddit 
) 

Какой в ​​идеале дали бы результаты:

subreddit1, subreddit2, subreddits_union, subreddits_interception 
----------------------------------------------------------------- 
    Art  | Politics |  50000  |  21000 
    Art  | Science |  92320  |  15000 
    ...  | ...  |  ...  |  ... 

Однако этот запрос дает мне следующую BigQuery ошибку: Error: Correlated subqueries that reference other tables are not supported unless they can be de-correlated, such as by transforming them into an efficient JOIN.

Который я понимаю. Однако я не думаю, что этот запрос может быть переведен в эффективное соединение. Учитывая, что BQ не имеет метода apply, можно ли каким-либо образом настроить этот запрос, не прибегая к индивидуальным запросам? Может быть, с PARTITION BY?

ответ

1

Thanks for your answer. This one works pretty well in returning the subreddit union , however, how would you implement the intersection ?

Может быть что-то вдоль линий

WITH top_most AS (
    SELECT subreddit, count(*) as n_comments 
    FROM `fh-bigquery.reddit_comments.2016_08` 
    GROUP BY subreddit 
    ORDER BY n_comments DESC 
    LIMIT 20 
), 
authors AS (
    SELECT DISTINCT author, subreddit 
    FROM `fh-bigquery.reddit_comments.2016_08` 
) 
SELECT 
count(DISTINCT a1.author), 
subreddit1, subreddit2 
FROM 
(
    SELECT t1.subreddit subreddit1, t2.subreddit subreddit2 
    FROM top_most t1 CROSS JOIN top_most t2 LIMIT 1000000 
) 
INNER JOIN authors a1 on a1.subreddit = subreddit1 
INNER JOIN authors a2 on a2.subreddit = subreddit2 
WHERE a1.author = a2.author 
GROUP BY subreddit1, subreddit2 
ORDER BY subreddit1, subreddit2 
+0

О, мужик, огромное спасибо! оба ваши запросы - именно то, что мне нужно, и они работают очень быстро! –

1

Не уверен, что я полностью понимаю вещи, которые вы пытаетесь вычислить. Но, может быть, этот пример может помочь придумать решение:

SELECT 
    subreddit1, 
    subreddit2, 
    COUNT(DISTINCT author) 
FROM 
`fh-bigquery.reddit_comments.2016_08` as f 
CROSS JOIN 
(SELECT a.subreddit as subreddit1, b.subreddit as subreddit2 
FROM (
    SELECT subreddit, count(*) as n_comments 
    FROM `fh-bigquery.reddit_comments.2016_08` 
    GROUP BY subreddit 
    ORDER BY n_comments DESC 
    LIMIT 10 
    ) a 
CROSS JOIN (
    SELECT subreddit, count(*) as n_comments 
    FROM `fh-bigquery.reddit_comments.2016_08` 
    GROUP BY subreddit 
    ORDER BY n_comments DESC 
    LIMIT 10 
    ) b 
WHERE a.subreddit < b.subreddit 
LIMIT 1000000 
) 
WHERE f.subreddit = subreddit1 OR f.subreddit = subreddit2 
GROUP BY subreddit1, subreddit2 
ORDER BY subreddit1, subreddit2 
+0

Спасибо за ваш ответ. Тем не менее, это хорошо работает при возврате соединения subreddit, как бы вы реализовали пересечение? –

Смежные вопросы