2017-07-19 59 views
1

我在BigQuery中有一列包含URL查詢字符串,例如a=1&c=1。我想在我的查詢中引用其中的一些,例如。用類似WHERE querystring.c = 1的東西過濾。BigQuery中的QueryString解析

我的計劃是將查詢字符串轉換爲JSON,然後使用JSON_EXTRACT。我想我可以編寫一個UDF來將查詢字符串轉換爲JSON,但是我仍然無法解決將node.js querystring package導入到我的UDF中的問題。

是否可以將一個node.js核心庫導入到UDF中,如果是這樣,如何實現?或者,有沒有更好的方法來實現我想要做的?

回答

1

另外還有更好的方法來實現我想要做的?

我想 - 是的 - 使用JS UDF是昂貴的資源明智,並有一定的侷限性。使用SQL UDF是更便宜,如果你願意,你可以通過使用SQL UDF低於轉變 - 但至少列出了你的「另類」的方式

對於上面的BigQuery標準SQL

#standardSQL 
WITH yourTable AS (
    SELECT 1 AS id, 'a=1&c=1' AS querystring UNION ALL 
    SELECT 2, 'c=2&b=3' 
) 
SELECT 
    id, 
    querystring, 
    SPLIT(kv, '=')[SAFE_OFFSET(0)] AS key, 
    SPLIT(kv, '=')[SAFE_OFFSET(1)] AS value 
FROM yourTable, UNNEST(SPLIT(querystring, '&')) AS kv 

允許理念你「解壓」的所有鍵值對,像這樣,現在下面

id querystring key value  
2 c=2&b=3  b 3  
1 a=1&c=1  c 1  
1 a=1&c=1  a 1  
2 c=2&b=3  c 2  

您可以在使用它們的WHERE子句像下面

#standardSQL 
WITH yourTable AS (
    SELECT 1 AS id, 'a=1&c=1' AS querystring UNION ALL 
    SELECT 2, 'c=2&b=3' 
) 
SELECT 
    id, 
    querystring, 
FROM yourTable, UNNEST(SPLIT(querystring, '&')) AS kv 
WHERE SPLIT(kv, '=')[SAFE_OFFSET(0)] = 'c' 
AND SPLIT(kv, '=')[SAFE_OFFSET(1)] = '1' 

這給了下面的結果

id querystring 
1 a=1&c=1  

注:這是方法只是快速和抽象插圖 - 我希望你能調整/它採用您的具體情況

下面是上面的例子來轉化的使用SQL UDF

#standardSQL 
CREATE TEMPORARY FUNCTION parse(qs STRING, key STRING) AS (
    (SELECT SPLIT(kv, '=')[SAFE_OFFSET(1)] FROM UNNEST(SPLIT(qs, '&')) AS kv WHERE SPLIT(kv, '=')[SAFE_OFFSET(0)] = key) 
); 
WITH yourTable AS (
    SELECT 1 AS id, 'a=1&c=1' AS querystring UNION ALL 
    SELECT 2, 'c=2&b=3' 
) 
SELECT 
    id, 
    querystring 
FROM yourTable 
WHERE parse(querystring, 'c') = '1' 

注:一般的查詢字符串沒有鑰匙的重複 - 因此擁有了DUP情況下沒有解決 - 但容易,如果需要:O)

但它不解碼任何編碼的組件,所以我的值仍然包含像%20這樣的東西。對此有何建議?

#standardSQL 
CREATE TEMPORARY FUNCTION parse(qs STRING, key STRING) AS (
    (SELECT SPLIT(kv, '=')[SAFE_OFFSET(1)] FROM UNNEST(SPLIT(qs, '&')) AS kv WHERE SPLIT(kv, '=')[SAFE_OFFSET(0)] = key) 
); 
CREATE TEMP FUNCTION decode(str STRING) 
RETURNS STRING 
LANGUAGE js AS """ 
    if (str == null) return null; 
    try { 
    return decodeURIComponent(str); 
    } catch (e) { 
    return str; 
    } 
"""; 
WITH yourTable AS (
    SELECT 1 AS id, 'a=1&c=1&d=a%20b%20c' AS querystring UNION ALL 
    SELECT 2, 'c=2&b=3' 
) 
SELECT 
    id, 
    querystring, 
    decode(parse(querystring, 'd')) as d 
FROM yourTable 
WHERE parse(querystring, 'c') = '1' 

結果是

id querystring    d  
-- -------------------  ----- 
1 a=1&c=1&d=a%20b%20c  a b c  
+0

這是一個很好的方法,但它不解碼任何編碼的組件,所以我的價值觀仍將包含之類的東西20%。對此有何建議? –

+0

好點。我對待你的問題更像是如何從查詢字符串中解析/提取鍵/值。在一個答案中很難涵蓋所有的細微差別。我建議你問一個新的問題具體到url解碼 - 我沒有看到這個問題 - 所以你有很好的機會得到答案 - 但正如我所說,期望涵蓋所有細微差異在一個職位是不現實的:o) –

+0

在我的答案中看到更新:o)。 –