Tüm Ürünler
Search
Belge Merkezi

MaxCompute:Örnek: KUD'larda karmaşık veri türlerini kullanma

Son Güncelleme:Oct 04, 2026

Yapılandırılmış verileri işleyen bir Kullanıcı Tanımlı İşlev (KUD) yazarken, MaxCompute karmaşık türlerini — ARRAY, MAP ve STRUCT — işleyici kodunuzdaki karşılık gelen Java veya Python türleriyle eşlemeniz gerekir. Bu konuda, üç karmaşık türün tamamında zaman damgalarını dönüştüren bir KUD'yu nasıl uygulayacağınız, dağıtacağınız ve çağıracağınız anlatılmaktadır.

Java KUD'ları yöntem aşırı yüklemeyi destekler; bu nedenle tek bir KUD adı tüm üç türü işler. Python KUD'ları ise her tür için ayrı bir işlev gerektirir.

Ön koşullar

Başlamadan önce şunlara sahip olduğunuzdan emin olun:

  • Bir MaxCompute projesi

  • Maven içeren bir Java geliştirme ortamı veya Python 3 ortamı

Tür eşlemeleri

Her MaxCompute karmaşık veri türü, KUD işleyicinizde belirli bir Java veya Python türüyle eşlenir:


MaxCompute türü


Java türü


Python türü


ARRAY


java.util.List


list


MAP


java.util.Map


dict


STRUCT


com.aliyun.odps.data.Struct


collections.namedtuple

STRUCT, Java'da @Resolve ek açıklamasını gerektirir. Yansıma (reflection), alan adlarını ve türlerini com.aliyun.odps.data.Struct üzerinden okuyamadığından ek açıklama bu bilgileri derleme zamanında sağlar. Ek açıklama yalnızca giriş parametreleri veya dönüş değeri Struct içeren aşırı yüklenmiş yöntemleri etkiler.

Adım 1: KUD'yu yazma

Java KUD'su

Java sınıfındaki üç evaluate yöntemi de UDF_COMPLEX_DATA adını paylaşır. MaxCompute çağrıları bağımsız değişken türüne göre yönlendirdiğinden her yöntem bir karmaşık türü işler.

SQL'deki KUD imzaları, doğrudan Java yöntem imzalarıyla eşleşir:

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(struct<input_name:string,input_timestamp:bigint> st)

Aşağıdaki bağımlılığı pom.xml dosyasına ekleyin:

<dependency>
  <groupId>com.aliyun.odps</groupId>
  <artifactId>odps-sdk-udf</artifactId>
  <version>0.29.10-public</version>
</dependency>
package com.aliyun; // Specify a package name.

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";

    /**
     * Convert a list of timestamps into a list of time strings.
     * @param timestamps Enter a list of timestamps.
     * @return Obtain a list of time strings.
     */
    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;
    }

    /**
     * Convert timestamps of the MAP data type into time strings of the MAP data type.
     * @param timestamps Enter data of the MAP data type in which values are timestamps.
     * @return Obtain a list of time strings of the MAP data type.
     */
    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;
    }

    /**
     * Convert a timestamp into a time string.
     * @param input Enter a timestamp of the STRUCT data type.
     * @return Obtain a time string of the STRUCT data type.
     */
    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;
    }
}

Giriş null olduğunda her evaluate yöntemi null döndürür. MaxCompute SQL alt ifadelerinin değerlendirme sırasını garanti etmez; bu nedenle null girişleri işlemek için KUD içindeki null denetimleri güvenilir bir yoldur.

Diğer kod gereksinimleri için bkz. Java KUD'ları.

Python KUD'su

Python KUD'ları yöntem aşırı yüklemeyi desteklemediğinden her karmaşık tür kendi adına sahip ayrı bir KUD gerektirir.

MaxCompute projeleri varsayılan olarak Python 2 çalıştırır. Python 3 kullanmak için Python 3 KUD'sunu çağırmadan önce oturum düzeyinde set odps.sql.python.version=cp37 komutunu çalıştırın.

Diğer Python 3 KUD gereksinimleri için bkz. Python 3 KUD'ları.

UDF_COMPLEX_DATA_ARRAY — ARRAY<BIGINT> girişini işler:

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

UDF_COMPLEX_DATA_MAP — MAP<STRING, BIGINT> girişini işler:

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

UDF_COMPLEX_DATA_STRUCT — STRUCT<input_name:STRING, input_timestamp:BIGINT> girişini işler:

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, input_namedtuple):
        OutputNamedTuple = collections.namedtuple('output_namedtuple', ['output_name', 'output_time'])
        name_val = input_namedtuple.input_name
        time_val = datetime.datetime.fromtimestamp(input_namedtuple.input_timestamp)
        output_namedtuple = OutputNamedTuple(name_val, time_val)
        return output_namedtuple

Adım 2: Kaynakları yükleme ve KUD oluşturma

KUD kodunuzu yazıp hata ayıkladıktan sonra bunu MaxCompute'e yükleyin ve KUD'yu kaydedin.

Adım 3: KUD'yu çağırma

ARRAY

-- Java UDF
SELECT UDF_COMPLEX_DATA(array(1554047999, 1554047989));

-- Python UDF (enable Python 3 first)
set odps.sql.python.version=cp37;
SELECT UDF_COMPLEX_DATA_ARRAY(array(1554047999, 1554047989));

Beklenen çıktı:

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

MAP

-- Java UDF
SELECT UDF_COMPLEX_DATA(map('date1', 1554047989, 'date2', 1554047999));

-- Python UDF (enable Python 3 first)
set odps.sql.python.version=cp37;
SELECT UDF_COMPLEX_DATA_MAP(map('date1', 1554047989, 'date2', 1554047999));

Beklenen çıktı:

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

STRUCT

-- Java UDF
SELECT UDF_COMPLEX_DATA(struct('date', 1554047989));

-- Python UDF (enable Python 3 first)
set odps.sql.python.version=cp37;
SELECT UDF_COMPLEX_DATA_STRUCT(struct('date', 1554047989));

Beklenen çıktı:

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

Ayrıca bkz.