Создание udf в bigquery для сопоставления входных данных массива - PullRequest
0 голосов
/ 19 июня 2020

Я пытаюсь создать udf для сопоставления массива в biqquery, по сути, если в массиве y есть значения массива x, тогда я хочу, чтобы результат был истинным.

например match_rows ([4,5 , 6], [5,6,7] должны вернуть истину.

Я написал это, но продолжаю получать синтаксические ошибки, и я недостаточно знаком с тем, что делаю, чтобы иметь возможность отладка, поэтому надеялся, что кто-то сможет пролить свет на то, что происходит.

Specifi c error = No matching signature for function match_rows for argument types: ARRAY, ARRAY. Supported signature: match_rows(ARRAY, ARRAY) at [44:1]

CREATE TEMP FUNCTION match_rows(arr1 ARRAY<FLOAT64>, arr2 ARRAY<FLOAT64>)
  RETURNS BOOL
  LANGUAGE js AS 
  """
function findCommonElements2(arr1, arr2) { 

    // Create an empty object 
    let obj = {}; 

        // Loop through the first array 
        for (let i = 0; i < arr1.length; i++) { 

            // Check if element from first array 
            // already exist in object or not 
            if(!obj[arr1[i]]) { 

                // If it doesn't exist assign the 
                // properties equals to the  
                // elements in the array 
                const element = arr1[i]; 
                obj[element] = true; 
            } 
        } 

        // Loop through the second array 
        for (let j = 0; j < arr2.length ; j++) { 

        // Check elements from second array exist 
        // in the created object or not 
        if(obj[arr2[j]]) { 
            return true; 
        } 
    } 
    return false; 
} 
""";

WITH input AS (
  SELECT STRUCT([5,6,7] as row, 'column2' as value) AS test
)
  SELECT
match_rows([4,4,6],[4,7,8]),
match_rows(test.row, test.row)

  FROM input ```

Ответы [ 2 ]

0 голосов
/ 19 июня 2020

Вместо использования ARRAY<FLOAT64> вы передаете ARRAY<INT64> своей функции. Следовательно, ошибка No matching signature. Чтобы решить эту ошибку, вы можете просто назначить одно из значений в вашем массиве как float, синтаксис ниже:

WITH input AS (
#notice that the first element is a float and so the whole array is ARRAY<FLOAT64>
  SELECT STRUCT([5.0,6,7] as row, 'column2' as value) AS test
)
  SELECT
#the same as it was done above, first element explicitly as float
match_rows([4.0,4,6],[4,7,8]),
match_rows(test.row, test.row)

  FROM input

Однако я протестировал вашу функцию и понял, что синтаксис ваш JavaScript UDF не соответствует документации . Синтаксис должен быть следующим:

CREATE TEMP FUNCTION multiplyInputs(x FLOAT64, y FLOAT64)
RETURNS FLOAT64
LANGUAGE js AS """
    //write directly your transformations here
    return x*y;
""";

Обратите внимание, что указывать function findCommonElements2(arr1, arr2) необязательно, вы можете go непосредственно в теле вашей функции, потому что имя функции определяется после оператора CREATE TEMP FUNCTION.

Кроме того, я также выяснил, что ваша функция не возвращала желаемый результат. По этой причине я написал более простой JavaScript UDF, который возвращает то, что вы ожидаете. Ниже синтаксис и тест:

CREATE TEMP FUNCTION match_rows(arr1 ARRAY<FLOAT64>, arr2 ARRAY<FLOAT64>)
  RETURNS BOOL
  LANGUAGE js AS 
  """
  //array of common elements betweent the two arrays
  var common_el= [];
  for(i=0;i < arr1.length;i++){
    for(j=0; j< arr2.length;j++){
      if(arr1[i] = arr2[j]){
        //add to the common_el array when the element is present in both arrays
        common_el.push(arr1[i]);
      }
    }
  }
  //if the array of common elements has at least one element return true othersie false 
  if(common_el.length > 0){return true;}else{return false;}
""";

WITH input AS (
  SELECT STRUCT([5.0,6,7] as row, 'column2' as value) AS test
)
  SELECT
match_rows([4.0,4,6],[4.0,5,7]) as check_1,
match_rows(test.row, test.row) as check_2

  FROM input#, unnest(test) as test

И вывод,

Row check_1 check_2
1   true    true
0 голосов
/ 19 июня 2020

Ниже для BigQuery Standard SQL

#standardSQL
CREATE TEMP FUNCTION match_rows(arr1 ANY TYPE, arr2 ANY TYPE) AS (
  (SELECT COUNT(1) FROM UNNEST(arr1) el JOIN UNNEST(arr2) el USING(el)) > 0
);
SELECT match_rows([4,5,6], [5,6,7])
...