Quando uma string de chave-valor contém caracteres delimitadores em suas chaves ou valores, a função integrada KEYVALUE não a analisa corretamente. Use a função definida pelo usuário (UDF) UDF_EXTRACT_KEY_VALUE_WITH_SPLIT para extrair valores dessas strings.
Este tópico descreve como escrever a UDF em Java ou Python, registrá-la no MaxCompute e chamá-la em SQL.
Etapas:
Assinatura da função
string UDF_EXTRACT_KEY_VALUE_WITH_SPLIT(string <s>, string <split1>, string <split2>, string <keyname>)
A função divide s em pares de chave-valor usando split1. Em seguida, separa cada par em chave e valor com split2 e retorna o valor correspondente à chave especificada por keyname.
Parâmetros (todos do tipo STRING e obrigatórios):
|
Parâmetro |
Descrição |
|
|
String a analisar |
|
|
Delimitador que separa os pares de chave-valor |
|
|
Delimitador que separa as chaves dos valores |
|
|
Chave cujo valor será retornado |
A função retorna null se qualquer parâmetro for null ou se a chave não for encontrada.
Pré-requisitos
Antes de começar, verifique se você tem:
Um projeto MaxCompute com permissões de desenvolvimento de UDF
Um ambiente de desenvolvimento Java ou Python para escrever e testar o código da UDF
1. Escrever a UDF
Escolha uma linguagem para implementar sua UDF. As três implementações produzem o mesmo resultado.
Java
package com.aliyun.rewrite; // The package name, which is user-defined.
import com.aliyun.odps.udf.UDF;
public class ExtractKeyValueWithSplit extends UDF{
/**
* Use split1 to split the string and obtain key-value pairs. Then, use split2 to split the key-value pairs and obtain the keys and values.
* @param str The source string.
* @param split1 The delimiter that is used to split a string and obtain key-value pairs.
* @param split2 The delimiter that is used to split key-value pairs and obtain the keys and values.
* @param keyname The name of the key whose value you want to obtain.
* @return The returned value.
*/
public String evaluate(String str, String split1, String split2, String keyname) {
if(str==null || split1==null || split2==null || keyname==null){
return null;
}
try {
// Combine keyname and split2.
String keySplit = keyname + split2;
// Traverse the string. Use split1 to split the string and obtain key-value pairs.
for(String subStr: str.split(split1)){
// Use split2 to split the key-value pairs and obtain the keys and values. Then, obtain the value that corresponds to a specific key.
if (subStr.startsWith(keySplit)){
return subStr.substring(keySplit.length());
}
}
} catch (Exception e) {
return null;
}
return null;
}
}
A UDF Java deve estender a classe UDF. O método evaluate define a assinatura da função usada nas instruções SQL: quatro parâmetros de entrada STRING e um valor de retorno STRING. Para outras especificações de código, consulte UDFs Java.
Python 3
Os projetos MaxCompute executam Python 2 por padrão. Para usar esta UDF Python 3, execute o seguinte comando no nível da sessão antes de chamá-la: set odps.sql.python.version=cp37.
from odps.udf import annotate
@annotate("string,string,string,string->string")
class ExtractKeyValueWithSplit(object):
def evaluate(self, s, split1, split2, keyname):
if not s:
return None
key_split = keyname + split2
# Traverse the string. Use split1 to split the string and obtain key-value pairs.
for subStr in s.split(split1):
# Use split2 to split the key-value pairs and obtain the keys and values. Then, obtain the value that corresponds to a specific key.
if subStr.startswith(key_split):
return subStr[len(key_split):]
Para especificações de UDFs Python 3, consulte UDFs Python 3.
Python 2
#coding:utf-8
from odps.udf import annotate
@annotate("string,string,string,string->string")
class ExtractKeyValueWithSplit(object):
def evaluate(self, s, split1, split2, keyname):
if not s:
return None
key_split = keyname + split2
# Traverse the string. Use split1 to split the string and obtain key-value pairs.
for subStr in s.split(split1):
# Use split2 to split the key-value pairs and obtain the keys and values. Then, obtain the value that corresponds to a specific key.
if subStr.startswith(key_split):
return subStr[len(key_split):]
Se o código da sua UDF Python 2 contiver caracteres chineses, adicione uma declaração de codificação no início do arquivo: #coding:utf-8 ou # -*- coding: utf-8 -*-. Sem essa declaração, o MaxCompute retorna um erro ao executar a UDF.
Para especificações de UDFs Python 2, consulte UDFs Python 2.
2. Carregar recursos e registrar a UDF
Após escrever e testar sua UDF, carregue o código no MaxCompute e registre-o como UDF_EXTRACT_KEY_VALUE_WITH_SPLIT.
UDF Java: Consulte Empacotar um programa Java, carregar o pacote e criar uma UDF do MaxCompute.
UDF Python: Consulte Carregar um programa Python e criar uma UDF do MaxCompute.
3. Usar a UDF
Depois de registrar a UDF, chame-a em uma instrução SQL. O exemplo a seguir extrai o valor da chave name de uma string em que o próprio valor contém o delimitador :.
set odps.sql.python.version=cp37; -- Required only for the Python 3 UDF. Omit this line for Java or Python 2.
SELECT UDF_EXTRACT_KEY_VALUE_WITH_SPLIT('name:zhangsang:man;age:2;', ';', ':', 'name');
Neste exemplo:
split1é;, que divide a string nos pares:name:zhangsang:maneage:2split2é:, que identifica a chave por correspondência de prefixoA função retorna tudo após
name:no primeiro par correspondente
Saída esperada:
+--------------+
| _c0 |
+--------------+
| zhangsan:man |
+--------------+
Próximos passos
Para analisar strings de chave-valor cujas chaves e valores não contêm delimitadores, consulte Obter os valores de strings sem delimitadores.
Para saber mais sobre o desenvolvimento de UDFs, consulte UDFs Java e UDFs Python 3.