日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

UDF示例:復雜數據類型

本文為您介紹如何在Java UDF和Python UDF中使用復雜數據類型。

命令說明

本示例將注冊一個名稱為UDF_COMPLEX_DATA的自定義函數。

說明

本示例將介紹array、map、struct三種復雜數據類型的使用。Java UDF通過重載的方式使用同一個自定義函數名。Python UDF需要分別注冊UDF_COMPLEX_DATA_ARRAY、UDF_COMPLEX_DATA_MAPUDF_COMPLEX_DATA_STRUCT實現上述三種數據類型的使用。

  • 命令格式:

    array<string> UDF_COMPLEX_DATA(array<bigint> <as>) 
    map<string, string> UDF_COMPLEX_DATA(map<string,bigint> <ms>) 
    struct<output_name:string,output_time:string> UDF_COMPLEX_DATA(<input_name:string,input_timestamp:bigint> <st>) 
  • 命令功能:

    將輸入的時間戳轉換成yyyy-MM-dd HH:mm:ss格式的時間字符串。其中入參分別使用到arraymap、struct復雜數據類型。

  • 參數說明:

    • as:ARRAY<BIGINT>類型,時間戳列表,必填。

    • ms:MAP<STRING, BIGINT>類型,其中value是時間戳,必填。

    • st:STRUCT類型,其中FIELD為input_timestamp的值是時間戳。

開發和使用步驟

1. 代碼開發

Java UDF 代碼示例

package com.aliyun; // package名稱,可以根據您的情況定義

import com.aliyun.odps.data.Struct;
import com.aliyun.odps.udf.UDF;
import com.aliyun.odps.udf.annotation.Resolve;

import java.text.SimpleDateFormat;
import java.util.*;

@Resolve("struct<input_name:string, input_timestamp:bigint>->map<string,string>")
public class ComplexDataTypeExample extends UDF{
    private static final String PATTERN = "yyyy-MM-dd HH:mm:ss";

    /**
     * 將時間戳列表轉換為時間字符串列表
     * @param timestamps 時間戳列表
     * @return 時間字符串列表
     */
    public List<String> evaluate(List<Long> timestamps) {
        if (timestamps == null) {
            return null;
        }
        List<String> result = new ArrayList<>();
        SimpleDateFormat formatter = new SimpleDateFormat(PATTERN);
        for (Long timestamp : timestamps) {
            Date date = new Date(timestamp < 9999999999L ? timestamp * 1000 : timestamp);
            String dateString = formatter.format(date);
            result.add(dateString);
        }
        return result;
    }

    /**
     * 將時間戳map轉換為時間字符串map
     * @param timestamps 時間戳map,其中value為時間戳
     * @return 時間字符串map
     */
    public Map<String, String> evaluate(Map<String, Long> timestamps) {
        if (timestamps == null) {
            return null;
        }
        Map<String, String> result = new HashMap<>(timestamps.size());
        SimpleDateFormat formatter = new SimpleDateFormat(PATTERN);
        for (String key : timestamps.keySet()) {
            Long timestamp = timestamps.get(key);
            Date date = new Date(timestamp < 9999999999L ? timestamp * 1000 : timestamp);
            String dateString = formatter.format(date);
            result.put(key, dateString);
        }
        return result;
    }

    /**
     * 將時間戳轉換為時間字符串
     * @param input 時間戳Struct
     * @return 時間字符串Struct
     */
    public Map<String, String> evaluate(Struct input) {
        if (input == null) {
            return null;
        }
        SimpleDateFormat formatter = new SimpleDateFormat(PATTERN);
        String nameValue = (String) input.getFieldValue("input_name");
        Long timestampValue = (Long) input.getFieldValue("input_timestamp");
        Date date = new Date(timestampValue < 9999999999L ? timestampValue * 1000 : timestampValue);
        String dateString = formatter.format(date);
        Map<String, String> result = new HashMap<>(8);
        result.put("output_name", nameValue);
        result.put("output_time", dateString);
        return result;
    }
}

示例代碼中,定義了3個重載的evaluate方法。其中:

  • 第一個用ARRAY作為參數,ARRAY對應java.util.List。

  • 第二個用MAP作為參數,MAP對應java.util.Map。

  • 第三個用STRUCT作為參數,STRUCT對應com.aliyun.odps.data.Struct。

    說明

    com.aliyun.odps.data.Struct無法通過反射分析獲取到field name和field type,需要輔助使用@Resolve annotation,即如果您需要在UDF中使用STRUCT,要求在UDF class上也標注上@Resolve注解,該注解只會影響參數或返回值中包含com.aliyun.odps.data.Struct的重載。

使用Java語言編寫UDF代碼必須繼承UDF類,本例中evaluate方法定義了三個string類型的入參和string類型的返回值,輸入參數和返回值的數據類型將作為SQL語句中UDF的函數簽名Signature,其他代碼規范和要求請參考:UDF開發規范與通用流程(Java)

Python3 UDF 代碼示例

下面示例中輸入數據類型為map<string,bigint>,該示例代碼在本文中將注冊為自定義函數:UDF_COMPLEX_DATA_MAP。

from odps.udf import annotate
import datetime
@annotate('map<string,bigint>->map<string,datetime>')
class MapExample:
    def evaluate(self, intput_dict):
        output_dict = dict()
        for key in intput_dict:
            value = intput_dict[key]
            t = datetime.datetime.fromtimestamp(value)
            output_dict[key] = t
        return output_dict

下面示例中輸入數據類型為array<bigint>,該示例代碼在本文中將注冊為自定義函數:UDF_COMPLEX_DATA_ARRAY。

from odps.udf import annotate
import datetime
@annotate('array<bigint>->array<datetime>')
class ArrayExample:
    def evaluate(self, intput_list):
        output_list = list()
        for item in intput_list:
            t = datetime.datetime.fromtimestamp(item)
            output_list.append(t)
        return output_list

下面示例中輸入數據類型為struct<input_name:string,input_timestamp:bigint>,該示例代碼在本文中將注冊為自定義函數:UDF_COMPLEX_DATA_STRUCT。

from odps.udf import annotate
import datetime, collections
@annotate('struct<input_name:string,input_timestamp:bigint>->struct<output_name:string,output_time:datetime>')
class StructExample:
    def evaluate(self, intput_namedtuple):
        OutputNamedTuple = collections.namedtuple('output_namedtuple', ['output_name', 'output_time'])
        name_val = intput_namedtuple.input_name
        time_val = datetime.datetime.fromtimestamp(intput_namedtuple.input_timestamp)
        output_namedtuple = OutputNamedTuple(name_val, time_val)
        return output_namedtuple

MaxCompute默認使用Python 2,可以在Session級別使用命令set odps.sql.python.version=cp37開啟Python 3。更多python3 UDF規范請參考:UDF開發規范與通用流程(Python3)。

2. 上傳資源和注冊函數

完成UDF代碼開發和調試之后,將資源上傳至MaxCompute并注冊函數,本示例注冊函數名:UDF_COMPLEX_DATA (Python UDF需要分別注冊函數名:UDF_COMPLEX_DATA_ARRAY、UDF_COMPLEX_DATA_MAPUDF_COMPLEX_DATA_STRUCT)。Java UDF上傳資源與注冊函數詳情步驟請參見:打包、上傳及注冊,Python UDF請參見:上傳及注冊。

3. 使用示例

成功注冊UDF后,執行以下命令,將時間戳(array類型)轉換為時間字符串。

set odps.sql.python.version=cp37; -- python3 UDF需要使用該命令開啟python3
SELECT UDF_COMPLEX_DATA(array(1554047999, 1554047989)); -- Java UDF調用
SELECT UDF_COMPLEX_DATA_ARRAY(array(1554047999, 1554047989)); -- Python UDF調用

執行結果如下:

+---------------------------------------------+
| _c0                                         |
+---------------------------------------------+
| [2019-03-31 23:59:59, 2019-03-31 23:59:49]  |
+---------------------------------------------+

執行以下命令,將時間戳(map類型)轉換為時間字符串。

set odps.sql.python.version=cp37; -- python3 UDF需要使用該命令開啟python3
SELECT UDF_COMPLEX_DATA_TYPE(map('date1', 1554047989, 'date2', 1554047999)); -- Java UDF調用
SELECT UDF_COMPLEX_DATA_TYPE_MAP(map('date1', 1554047989, 'date2', 1554047999)); -- Python UDF調用

執行結果如下:

+----------------------------------------------------------------+
| _c0                                                            |
+----------------------------------------------------------------+
| {"date1":"2019-03-31 23:59:49","date2":"2019-03-31 23:59:59"}  |
+----------------------------------------------------------------+

執行以下命令,將時間戳(struct類型)轉換為時間字符串。

set odps.sql.python.version=cp37; -- python3 UDF需要使用該命令開啟python3
SELECT UDF_COMPLEX_DATA_TYPE(struct('date', 1554047989)); -- Java UDF調用
SELECT UDF_COMPLEX_DATA_TYPE_MAP(struct('date', 1554047989)); -- Python UDF調用

執行結果如下:

+-------------------------------------------------------------+
| _c0                                                         |
+-------------------------------------------------------------+
| {"output_name":"date","output_time":"2019-03-31 23:59:49"}  |
+-------------------------------------------------------------+