2017-02-16 45 views
1

我設法使用Web UI和UDF進行查詢。當我把它移植到我的嵌入代碼時,我得到了一個400回覆,「缺少必需的參數」。我有我的JavaScript代碼在谷歌雲存儲桶中,我用Web UI選項測試它使用外部代碼而不是UDF編輯框中的代碼。你要清楚該文本框,然後選擇這條線在選項區域中的鏈接:BIgQuery UDF Javascript在網絡用戶界面中工作但未嵌入

UDF Source URIs Edit Inline UDF 

因此,這意味着BQ的Web UI是找到我的UDF和它的作品一樣,在該UDF編輯器相同的代碼。我的猜測是請求格式不正確。

我正在按照文檔修改查詢......文檔是[here] [1],顯然只是完整請求API的一個片段。

"configuration": { 
    "query": { 
     "userDefinedFunctionResources": [ 
     { 
      "inlineCode": "var someCode = 'here';" 
     }, 
     { 
      "resourceUri": "gs://some-bucket/js/lib.js" 
     } 
     ], 
     "query": "select a from myFunc(T);" 
    } 
    } 

我的解釋是這樣:

var request = gapi.client.bigquery.jobs.query({ 
     'projectId': project_id, 
     'timeoutMs': '60000', 
     'configuration': { 
      'query' : { 
       'userDefinedFunctionResources': [ 
       { 
        'inlineCode' : '' 
       }, 
       { 
        'resourceUri': 'gs://cloudfiledatetype/UDF/udfLatestProcTimeAllRegions.js' 
       } 
       ], 
       'query': queryAll 
      } 
     } 
    }); 

順便說一句,我試圖刪除inLineCode選項,並得到了同樣的錯誤。 有關於如何格式化完整的請求沒有文檔...

作爲測試,我刪除了參考UDF和刪除的配置選項,因此請求是麪包,黃油:

var request = gapi.client.bigquery.jobs.query({ 
     'projectId': project_id, 
     'timeoutMs': '60000', 
     'query': queryAll 
    }); 

這工作正常:沒有400錯誤。

我的猜測是我的請求中有錯誤,但我無法在Google網站或SO中找到更詳細的示例。

我還讀到,有人擔心UDF生活在一個正在被剝奪。我正在使用UDF,因爲如果沒有它,我無法獲得所需的查詢。我可以用LAG做它,但查詢總是被OVER定義上的格式選項拒絕... Arggg ..

完整的高級功能的真實生活實例真的很受讚賞Google。

爲了更好的文檔:這裏是我的UDF:

var lastInputA = -1; 
    function passthroughExample(row, emit) { 

    // handle 
    if (row.inputA != lastInputA) { 
     emit({outputC: row.inputC}); 
    } 
    lastInputA = row.inputA; 
    } 


    bigquery.defineFunction(
    'passthrough',       // Name of the function exported to SQL 
    ['inputA', 'inputB', 'inputC'],   // Names of input columns 
    [{'name': 'outputC', 'type': 'integer'}], 
    passthroughExample      // Reference to JavaScript UDF 
); 

它做的東西很簡單,但我已經看到了如何處理類似的問題上SO一對夫婦的職位。 我有多個entier與相同的進程窗口,每天的startTime和endTime,但在不同的日子處理不同的進程時間。我想選擇後者,因爲它有最新的代碼。注意代碼只輸出最新的處理時間。這樣,在查詢我能做到這一點

WHERE 
     processTime IN ((
     SELECT 
     outputC 
     FROM 
     passthrough (
     SELECT 
      summaryStartTimeStamp AS inputA, 
      summaryEndTimeStamp AS inputB, 
      processTime AS inputC 

如果你做一個查詢來獲取所有的日子,爲了與上升開始時間和下降過程時,你得到了最新的處理時間,然後行具有重複的startTime和endTime以及更早的處理時間的行。因此,UDF找到startTime更改併發出此行的時間。它會拒絕行,直到startTime再次更改。

以下是UDF之前的數據示例。這是UDF的輸入。

summaryStartTimeStamp summaryEndTimeStamp processTime 
1468206000000 1468292400000 1478668368824 
1468206000000 1468292400000 1474504378494 
1468206000000 1468292400000 1472261683703 
1468206000000 1468292400000 1471908635453 
1468292400000 1468378800000 1478668668857 
1468292400000 1468378800000 1474504654098 
1468292400000 1468378800000 1472261923772 
1468292400000 1468378800000 1471908956622 
1468378800000 1468465200000 1478669028973 
1468378800000 1468465200000 1474504910553 
1468378800000 1468465200000 1472262223831 
1468378800000 1468465200000 1471916440493 
1468465200000 1468551600000 1478669269089 
1468465200000 1468551600000 1474505174929 
1468465200000 1468551600000 1472262463965 
1468465200000 1468551600000 1471917212326 

這裏的UDF的輸出與redudant線取出,並在outputC最新的處理時間

outputA   outputB   outputC 
1468206000000 1468292400000 1478668368824 
1468292400000 1468378800000 1478668668857 
1468378800000 1468465200000 1478669028973 
1468465200000 1468551600000 1478669269089 

這裏是在WebUI使用UDF查詢...

SELECT 
    outputA, outputB, outputC 
FROM 
    passthrough (
    SELECT summaryStartTimeStamp as inputA, summaryEndTimeStamp as inputB, processTime as inputC 
    FROM 
    [xxx removed ] 
    WHERE 
    eventType == "MAPFIT" 
    GROUP BY 
    inputA, inputB, inputC 
    ORDER BY 
    inputA,inputC DESC 
    LIMIT 
    1000) 
ORDER by outputA 
LIMIT 1000 

在UDF編輯器窗口中使用此UDF

var lastInputA = -1; 
function passthroughExample(row, emit) { 

    // handle 
    if (row.inputA != lastInputA) { 
     emit({outputC: row.inputC}); 
    } 
    lastInputA = row.inputA; 
} 


bigquery.defineFunction(
    'passthrough',       
    ['inputA', 'inputB', 'inputC'],   
    [{'name': 'outputC', 'type': 'integer'}], 
    passthroughExample      
); 

在這個例子中,我輸出了可讀性的開始和結束時間。在內聯代碼中,我使用了只輸出處理時間的修改版本,因此請選擇子查詢中的進程時間。

我可以做到這一點沒有UDF通過具有相同的查詢,然後檢測與startTime不等於startTime滯後一。

我的問題是:爲什麼在這個問題上的JavaScript格式的請求缺少必要的參數..謝謝

更新: 我一直在試圖請求定義的所有可能的組合,我有一個不同錯誤現在..我擺脫了「400:所需參數丟失」的錯誤。現在我得到「400,未知的TVF:直通」。 「passthrough」是UDF的名稱。

所以看起來請求的JSON解析器已滿足配置,但它仍然無法找到UDF。這裏是新的請求定義:

requests = gapi.client.bigquery.jobs.query({ 
     'projectId': project_id, 
     'timeoutMs': '60000', 
     "userDefinedFunctionResources": [ 
      { 
       "resourceUri": "gs://cloudfiledatetype/UDF/udfLatestProcTimeAllRegions.js" 
      }, 
     ], 
     'query': queryAll 

}); 

請注意,如果我在WebUI中發出查詢並指向此UDF,它運行良好。因此,我認爲這個問題只是嵌入式工作。

我也嘗試以另一種方式添加相同的功能:現在我使用了這個請求,其中UDF作爲javascript blob添加到「inLineCode」選項中。

requests = gapi.client.bigquery.jobs.query({ 
     'projectId': project_id, 
     'timeoutMs': '60000', 
     "userDefinedFunctionResources": [ 
      { 
      "inlineCode": "var lastInputA = -1; function passthroughExample(row, emit) { if (row.inputA != lastInputA) { emit({outputC: row.inputC}); } lastInputA = row.inputA;} bigquery.defineFunction( 'passthrough', ['inputA', 'inputB', 'inputC'], [{'name': 'outputC', 'type': 'integer'}], passthroughExample);" 
      } 
     ], 
     'query': queryAll 

}); 

再一次,我得到了一個「未知TVF:直通」的400響應。 所以我不知道爲什麼這是失敗的......這是我的請求定義還是UDF不工作的WebUI外?謝謝。

P.S.如果有人可以將Big Query標籤和UserDefinedFunctions標籤添加到這個問題的標籤頁中,那就非常感謝。否則,在谷歌的人可能看不到這一點....

+0

任何人只要有足夠的積分,請能夠改變這個標籤,包括大的查詢和UserdefinedFunctions以便在谷歌的傢伙可以看到它。我認爲它的功能相當基本的問題......其在WebUI中的工作正常,但沒有在正常的工作調用......感謝 – Paul

回答

相關問題