google-bigquery - 使用 BYTES 数据类型的 BigQuery UDF

标签 google-bigquery user-defined-functions

我目前正在尝试使用 Javascript 中的用户定义函数来计算 BigQuery 中两个二进制字符串之间的汉明距离,我的架构非常简单:

row_id        STRING    
descriptors   BYTES REPEATED    
phash         BYTES

我发现有点令人困惑的是,您显然将 BigQuery 中的 BYTES 作为 Base64 字符串处理,我导入了两个函数 atob()btoa() 因此我可以使用字节字符串的二进制形式而不是 Base64 表示形式:

我的查询当前如下所示:

CREATE TEMP FUNCTION f_PHASH_distance(ph1 BYTES, ph2 BYTES)
    RETURNS INT64
   LANGUAGE js AS
   """
        return HammingDistance(ph1, ph2);
   """
    OPTIONS (
        library=["gs://test.appspot.com/HammingDistance.js",
                 "gs://test.appspot.com/btoa_atob.js"]
    );

SELECT f_PHASH_distance(phash, CAST("9Slp3g9OgVI=" AS BYTES)) 
  FROM ims.images WHERE row_id = "2333USX"

id = "2333USX"phash 的行等于 base64 中的“9Slp3g9OgVI=”,这意味着汉明距离为 0。但我目前在 BigQuery 上得到的不是 0,而是 35。

HammingDistance.js 具有以下内容:

function HammingDistance(a, b){
    var count = 0;
    for(var i = 0; i < a.length; i++){
        // calculate XOR between the two chars
        var xor = a.charCodeAt(i) ^ b.charCodeAt(i);
        // count number of 1's on the result
        for(var j = 0; j < 16; j++){
            //add if LSB is 1
            count += xor % 2;
            //right shift the variable
            xor = xor >> 1;
        }
    }
    return count;
}

/**
 *  Calculates the distance between two Perceptual hashes of two images encoded
 *  in base 64
 */
function PHASHDistance(a, b){
    return HammingDistance(atob(a), atob(b));
} 

并在浏览器的 JS 控制台中测试它,我确实得到了预期的结果。因此,我假设我在转换方面做错了什么,但关于具有 BYTE 参数的 UDF 的文档非常缺乏。

任何帮助将不胜感激。

最佳答案

看起来问题在于您正在将 "9Slp3g9OgVI=" 转换为字节,而不是将其从 base64 转换为字节。我认为你想要这个:

SELECT f_PHASH_distance(phash, FROM_BASE64("9Slp3g9OgVI=")) 
FROM ims.images WHERE row_id = "2333USX"

不过,您可能最好使用 SQL 函数而不是 JavaScript 函数,因为 JavaScript 通常没有那么快。下面是 SQL 中的汉明距离实现,假设字节长度相等:

#standardSQL
CREATE TEMP FUNCTION HammingDistance(b1 BYTES, b2 BYTES) AS (
  BIT_COUNT(b1 ^ b2)
);

WITH Input AS (
  SELECT b'defdef' AS bytes UNION ALL
  SELECT b'123de4' UNION ALL
  SELECT b'abc123'
)
SELECT HammingDistance(b'abcdef', bytes)
FROM Input;

它对两个字节值进行按位异或,然后检查有多少位不相同。

关于google-bigquery - 使用 BYTES 数据类型的 BigQuery UDF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45038781/

相关文章:

kubernetes - 基于 Pod 或部署的 GKE 账单明细

带有循环和管道的 bash 函数

从 Shiny 的用户定义函数返回无功输出

vba - 引用 UDF 中的特定单元格

r - 使用替代语法方法在 R 中定义函数

function - 用户定义函数与内置/预定义函数

google-bigquery - 什么是 bigquery 键盘快捷键?

mysql - 我如何同步调用 google-bigquery 删除和插入 API?

sql - 如何在 SQL 中对 COUNT 列表求和

google-bigquery - RAND() 在 BigQuery 中如何工作?