Cet exemple montre comment écrire une fonction définie par l'utilisateur (UDF) nommée UDF_EXTRACT_KEY_VALUE pour extraire une valeur d'une chaîne de paires clé-valeur utilisant des délimiteurs personnalisés, par exemple name:zhangsan;age:21;.
Cette UDF est conçue pour les chaînes sans délimiteurs fixes. Pour analyser des chaînes comportant déjà des délimiteurs standard, consultez la rubrique Exemple : Obtenir les valeurs de chaînes avec délimiteurs.
Fonctionnement
La fonction UDF_EXTRACT_KEY_VALUE divise une chaîne en deux passes :
Utilisez
split1pour diviser la chaîne en paires clé-valeur.Utilisez
split2pour diviser chaque paire en une clé et une valeur.Renvoyez la valeur correspondant à la clé spécifiée par
keyname.
Syntaxe
STRING UDF_EXTRACT_KEY_VALUE(STRING <s>, STRING <split1>, STRING <split2>, STRING <keyname>)
Paramètres
|
Paramètre |
Type |
Obligatoire |
Description |
|
|
STRING |
Oui |
Chaîne source |
|
|
STRING |
Oui |
Délimiteur séparant les paires clé-valeur |
|
|
STRING |
Oui |
Délimiteur séparant les clés des valeurs au sein de chaque paire |
|
|
STRING |
Oui |
Clé dont vous souhaitez récupérer la valeur |
Valeur de retour : STRING — la valeur de la clé spécifiée, ou NULL si la clé est introuvable ou si l'entrée est vide.
Prérequis
Avant de commencer, assurez-vous de disposer des éléments suivants :
Un projet MaxCompute avec les permissions de création d'UDF
Le client MaxCompute ou DataWorks DataStudio pour télécharger les ressources et enregistrer l'UDF
Écrire l'UDF
Choisissez un langage et implémentez la logique de l'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]);
}
}
}
La méthode evaluate définit quatre paramètres d'entrée STRING et renvoie une valeur STRING. Cette signature devient la signature SQL de l'UDF. Pour les spécifications des UDF Java, consultez la rubrique UDF 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)
Les projets MaxCompute utilisent Python 2 par défaut. Pour utiliser cette UDF Python 3, exécutez la commande suivante au niveau de la session avant d'appeler l'UDF :
set odps.sql.python.version=cp37;
Pour les spécifications des UDF Python 3, consultez la rubrique UDF 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)
Si le code de votre UDF contient des caractères chinois, ajoutez une déclaration d'encodage (#coding:utf-8 ou # -*- coding: utf-8 -*-) en haut du fichier pour éviter les erreurs d'exécution. Pour les spécifications des UDF Python 2, consultez la rubrique UDF Python 2.
Télécharger les ressources et enregistrer l'UDF
Après avoir développé et testé le code de votre UDF, téléchargez-le sur MaxCompute et enregistrez l'UDF sous le nom UDF_EXTRACT_KEY_VALUE.
Java : Consultez la rubrique Empaqueter un programme Java, télécharger le package et créer une UDF MaxCompute.
Python : Consultez la rubrique Télécharger un programme Python et créer une UDF MaxCompute.
Exécuter l'UDF
Après avoir enregistré l'UDF, exécutez l'instruction SQL suivante pour extraire la valeur de la clé name de la chaîne 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');
Résultat attendu :
+----------+
| _c0 |
+----------+
| zhangsan |
+----------+
Étapes suivantes
Pour analyser des chaînes comportant des délimiteurs intégrés standard, consultez la rubrique Exemple : Obtenir les valeurs de chaînes avec délimiteurs.
Pour en savoir plus sur le cycle de vie du développement des UDF, consultez les rubriques UDF Java et UDF Python 3.