Este exemplo demonstra como escrever uma função definida pelo usuário (UDF) chamada UDF_EXTRACT_KEY_VALUE para extrair um valor de uma string de pares chave-valor com delimitadores personalizados, como name:zhangsan;age:21;.
Esta UDF foi projetada para strings sem delimitadores fixos. Para analisar strings que já possuem delimitadores padrão, consulte Exemplo: Obter os valores de strings com delimitadores .
Funcionamento
A função UDF_EXTRACT_KEY_VALUE divide a string em duas etapas:
Use
split1para dividir a string em pares chave-valor.Use
split2para separar cada par em chave e valor.Retorne o valor da chave especificada por
keyname.
Sintaxe
STRING UDF_EXTRACT_KEY_VALUE(STRING <s>, STRING <split1>, STRING <split2>, STRING <keyname>)
Parâmetros
|
Parâmetro |
Tipo |
Obrigatório |
Descrição |
|
|
STRING |
Sim |
String source |
|
|
STRING |
Sim |
Delimitador que separa os pares chave-valor |
|
|
STRING |
Sim |
Separador entre chaves e valores dentro de cada par |
|
|
STRING |
Sim |
Chave cujo valor se deseja recuperar |
Valor de retorno: STRING — o valor da chave especificada ou NULL caso a chave não seja encontrada ou a entrada esteja vazia.
Pré-requisitos
Antes de começar, verifique se você possui:
Um projeto MaxCompute com permissões para criar UDFs
O cliente MaxCompute ou o DataWorks DataStudio para fazer upload de resources e registrar a UDF
Escrever a UDF
Escolha uma linguagem e implemente a lógica da UDF.
Java
package com.aliyun.rewrite; // Specify a package name.
import com.aliyun.odps.udf.UDF;
import java.util.HashMap;
import java.util.Map;
public class ExtractKeyValue extends UDF {
private static final int KEY_VALUE_LENGTH = 2;
/**
* Extracts the value for a given key from a delimited string.
* @param str The source string.
* @param split1 The delimiter that separates key-value pairs.
* @param split2 The delimiter that separates keys from values.
* @param keyname The key whose value you want to retrieve.
* @return The value of the specified key, or null if not found.
*/
public String evaluate(String str, String split1, String split2, String keyname) {
try {
// Return null for empty or null input.
if (str == null || "".equals(str)) {
return null;
}
Map<String, String> keyValueCache = new HashMap<>(8);
String[] extractedKeyValues = str.split(split1);
// Split each key-value pair and store the result.
for (String keyValue : extractedKeyValues) {
storeKeyValue(keyValueCache, keyValue, split2);
}
// Return the value for the specified key.
return keyValueCache.get(keyname);
} catch (Exception e) {
return null;
}
}
/**
* Splits a key-value pair and stores it in the cache.
* @param keyValueCache The map to store the parsed key-value pairs.
* @param keyValue A single key-value pair string.
* @param split The delimiter between the key and value.
*/
private void storeKeyValue(Map<String, String> keyValueCache, String keyValue, String split) {
if (keyValue == null || "".equals(keyValue)) {
return;
}
String[] keyValueArr = keyValue.split(split);
if (keyValueArr.length == KEY_VALUE_LENGTH) {
keyValueCache.put(keyValueArr[0], keyValueArr[1]);
}
}
}
O método evaluate define quatro parâmetros de entrada STRING e retorna um valor STRING. Essa assinatura torna-se a assinatura SQL da UDF. Para especificações de UDFs Java, consulte UDFs Java.
Python 3
from odps.udf import annotate
@annotate("string,string,string,string->string")
class ExtractKeyValue(object):
def evaluate(self, s, split1, split2, keyname):
if not s:
return None
# Split the string into key-value pairs, then split each pair into a key and value.
key_value_cache = dict(kv.split(split2) for kv in s.split(split1) if kv)
# Return the value for the specified key.
return key_value_cache.get(keyname)
Projetos MaxCompute executam Python 2 por padrão. Para usar esta UDF em Python 3, execute o comando abaixo no nível da sessão antes de chamar a UDF:
set odps.sql.python.version=cp37;
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 ExtractKeyValue(object):
def evaluate(self, s, split1, split2, keyname):
if not s:
return None
# Split the string into key-value pairs, then split each pair into a key and value.
key_value_cache = dict(kv.split(split2) for kv in s.split(split1) if kv)
# Return the value for the specified key.
return key_value_cache.get(keyname)
Se o código da UDF contiver caracteres chineses, adicione uma declaração de codificação (#coding:utf-8 ou # -*- coding: utf-8 -*-) no início do arquivo para evitar erros de execução. Para especificações de UDFs Python 2, consulte UDFs Python 2.
Fazer upload de resources e registrar a UDF
Após desenvolver e testar o código da UDF, faça o upload para o MaxCompute e registre a UDF como UDF_EXTRACT_KEY_VALUE.
Java: Consulte Empacotar um programa Java, fazer upload do pacote e criar uma UDF MaxCompute.
Python: Consulte Fazer upload de um programa Python e criar uma UDF MaxCompute.
Executar a UDF
Depois de registrar a UDF, execute o SQL a seguir para extrair o valor da chave name de name:zhangsan;age:21;:
-- To use a Python 3 UDF, run this line first.
set odps.sql.python.version=cp37;
SELECT UDF_EXTRACT_KEY_VALUE('name:zhangsan;age:21;', ';', ':', 'name');
Saída esperada:
+----------+
| _c0 |
+----------+
| zhangsan |
+----------+
Próximos passos
Para analisar strings com delimitadores internos padrão, consulte Exemplo: Obter os valores de strings com delimitadores.
Para saber mais sobre o ciclo de vida de desenvolvimento de UDFs, consulte UDFs Java e UDFs Python 3.