google-bigquery - BYTES 的按位二元运算符要求输入的长度相等。左侧有 16 个字节,右侧有 4 个字节
问题描述
我正在尝试使用他们的 IP 将用户与他们的地理位置相匹配。
IPs 是 ipv4、ipv6 和一些带有无效条目的行的混合。
我使用 Felipe Hoffa https://towardsdatascience.com/geolocation-with-bigquery-de-identify-76-million-ip-addresses-in-20-seconds-e9e652480bd2的这篇文章中的说明将我的 IP 与块文件。
问题是尝试使用 NET.SAFE_IP_FROM_STRING(ip_address) 和 NET.IP_NET_MASK(4,mask) 函数时出现错误。错误是:
BYTES 的按位二元运算符要求输入的长度相等。左侧有 16 个字节,右侧有 4 个字节。
所以我尝试在使用正则表达式将 IP 传递给函数之前确保它们是有效的。这适用于 ipv4。我现在也想出了匹配 ipv6 的正则表达式,从我的检查来看,它似乎是准确的。但是我仍然得到错误。我不知道为什么以及如何修复我的查询以获得正确的结果。
请参阅下面的整个查询:
(
SELECT
*,
NET.SAFE_IP_FROM_STRING(ip_address) & NET.IP_NET_MASK(4,
mask) network_bin
FROM (
SELECT
* EXCEPT (is_valid)
FROM (
SELECT
*,
CASE
WHEN (REGEXP_CONTAINS(ip_address, r'\A[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7}\z') OR (NOT REGEXP_CONTAINS(ip_address, r'\A(.*?[a-f0-9](:|\z)){8}') AND REGEXP_CONTAINS(ip_address, r'\A([a-f0-9]{1,4}(:[a-f0-9]{1,4}){0,6})?::([a-f0-9]{1,4}(:[a-f0-9]{1,4}){0,6})?\z')) OR REGEXP_CONTAINS(ip_address, r'\A[a-f0-9]{1,4}(:[a-f0-9]{1,4}){5}:(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}\z') OR (NOT REGEXP_CONTAINS(ip_address, r'\A(.*?[a-f0-9]:){6}') AND REGEXP_CONTAINS(ip_address, r'\A([a-f0-9]{1,4}(:[a-f0-9]{1,4}){0,4})?::([a-f0-9]{1,4}:){0,5}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}\z')) ) THEN TRUE
WHEN REGEXP_CONTAINS(ip_address, r"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$") THEN TRUE
ELSE
FALSE
END
AS is_valid
FROM (
SELECT
user,
ip_address,
date
FROM
`project.dataset.table`)
WHERE
is_valid IS TRUE),
UNNEST(GENERATE_ARRAY(9,32)) mask)
解决方案
问题可能是 NET.SAFE_IP_FROM_STRING 返回 4 个字节的 IPv4 和 16 个字节的 IPv6。& NET.IP_NET_MASK(4, mask)
IPv4 也可以,但对于 IPv6,您需要使用& NET.IP_NET_MASK(16, mask)
. 一种选择是引入类似的东西并像这样is_ipv4
使用它:
IF(
is_ipv4,
NET.SAFE_IP_FROM_STRING(ip_address) & NET.IP_NET_MASK(4, mask),
NET.SAFE_IP_FROM_STRING(ip_address) & NET.IP_NET_MASK(16, mask)
) network_bin
推荐阅读
- php - 使用 Levenshtein 距离重新排列单词
- assembly - 如何解决 TASM 中的“假设数据段是 32 位”
- firebase - 未找到 Travis 部署 Firebase 托管文件
- javascript - Style.backgroundColor 或 style.background 没有执行它的功能
- c++ - godot的NetSocket是如何创建实例的?
- python - python url请求响应解码
- mongodb - 本地数据库 + 服务器数据库 - React Native
- r - 错误:更改堆积条形图 ggplot2 中的颜色
- javascript - 如何通过更灵活地渲染其他转储组件来使 React 中的智能组件更加智能
- angular - 如何在返回函数之前等到所有订阅都运行?