Object Table常用UDF(Java)

更新时间:
复制 MD 格式

本文介绍在MaxCompute Object Table场景中,用于非结构化文件元数据提取与格式识别的常用Java UDF,包括函数说明和使用步骤。

在 AI 数据处理场景中,对非结构化数据(如图片、音视频、PDF、Office 文档等)进行元数据提取与预处理,是 Object Table 的典型用途。非结构化数据存储在 OSS 中,需要在进入模型训练、内容理解或检索增强(RAG)等流程前,批量提取文件元数据,例如:

  • 从图像中提取尺寸、格式、EXIF信息等。

  • 从音视频文件中获取时长、采样率、编码格式、关键帧等。

  • PDFWord文档中解析页数、作者、创建时间等。

基于Object Table能力,MaxCompute 提供以下 Java UDF,支持在 SQL 层面对存储在对象存储中的文件进行元信息提取与轻量级预处理。提取结果可用于构建结构化元数据表、过滤或采样数据集,以及为 AI 特征工程、向量化等下游任务提供输入。

下载 Java UDF jar

下载 Java UDF jar包:lakehouse-udf-1.0-SNAPSHOT.jar

AI-UDF 列表

GetFileMeta

GetFileMeta用于获取文件的元数据,返回类型为Map<String, String>

  • 支持的文件格式

    类型

    支持格式

    图片

    jpg、jpeg、png、bmp、gif、tif、tiff

    音视频

    mp3、mp4、avi、wav

    办公文档

    pdf、doc、docx、ppt、pptx、xls、xlsx

  • 方法

    evaluate(Binary data, String fileFormat)
    evaluate(Binary data, String fileFormat, String metadataKeyDelimiter)
    evaluate(Binary data, String fileFormat, String metadataKeyDelimiter, String parseFailPolicy)
    evaluate(Binary data, String fileFormat, Map<String, String> options)
  • options参数说明

    参数名

    类型

    默认值

    说明

    metadataKeyDelimiter

    String

    "."

    多层级元数据键名的分隔符。(如有多层级表示,则使用该参数。)

    在图片类文件中,作为元数据"目录"与"标签"的分隔符。例如:

    • 默认:"EXIF.DateTimeOriginal"

    • 自定义/"EXIF/DateTimeOriginal"

    password

    String

    null

    加密PDF文件的密码。仅对pdf格式有效,其他加密文件(如Office加密文档)暂不支持。

    parseFailPolicy

    String

    "OUTPUT_NULL"

    解析失败时的处理策略,取值如下:

    • OUTPUT_DEFAULT:静默返回null。

    • OUTPUT_NULL:静默返回null。

    • WARN_AND_NULL:输出警告日志后返回null。

    • THROW_EXCEPTION:抛出异常,中断流程。

    metadataKeyExclusionRegex

    String

    null

    元数据键名正则过滤器,移除命中正则表达式的元数据项,多个规则以逗号分隔。例如:

    • "Photoshop.*"(移除键名以Photoshop开头的条目)

    • ".*Path Info.*"(移除键名含Path Info子串的条目)

GetFileFormat

GetFileFormat用于提取文件的详细格式,例如jsoncsvorcparquet等,返回类型为String

  • 方法

    • 用法一:根据文件名提取格式

      evaluate(String fileName, String parseFailPolicy)
    • 用法二根据二进制数据和文件名提取格式。

      evaluate(Binary data, String fileName, String parseFailPolicy)
  • options参数说明

    parseFailPolicy:解析失败时的处理策略。String类型。默认值为"OUTPUT_NULL",取值如下:

    • OUTPUT_DEFAULT:静默返回null。

    • OUTPUT_NULL:静默返回null。

    • WARN_AND_NULL:输出警告日志后返回null。

    • THROW_EXCEPTION:抛出异常,中断流程。

GetFileMediaType

GetFileMediaType用于根据IANA注册表检测文件的顶级MIME媒体类型,返回类型为String

  • 支持媒体类型:

    • application(应用)

    • audio(音频)

    • example(示例)

    • font(字体)

    • haptics(触觉)

    • image(图像)

    • message(消息)

    • model(模型)

    • multipart(多部分)

    • text(文本)

    • video(视频)

  • 方法

    • 用法一:根据文件名提取格式

      evaluate(String fileName, String parseFailPolicy)
    • 用法二根据二进制数据和文件名提取格式

      evaluate(Binary data, String fileName, String parseFailPolicy)
  • options参数说明

    parseFailPolicy:解析失败时的处理策略。String类型。默认值为"OUTPUT_NULL",取值如下:

    • OUTPUT_DEFAULT:静默返回null。

    • OUTPUT_NULL:静默返回null。

    • WARN_AND_NULL:输出警告日志后返回null。

    • THROW_EXCEPTION:抛出异常,中断流程。

GetFileContentType

GetFileContentType用于返回文件的完整MIME内容类型(Content-Type),返回类型为String

  • 方法

    • 用法一:根据文件名检测内容类型

      evaluate(String fileName, String parseFailPolicy)
    • 用法二根据二进制数据和文件名检测内容类型

      evaluate(Binary data, String fileName, String parseFailPolicy)
  • options参数说明

    parseFailPolicy:解析失败时的处理策略。String类型。默认值为"OUTPUT_NULL",取值如下:

    • OUTPUT_DEFAULT:静默返回null。

    • OUTPUT_NULL:静默返回null。

    • WARN_AND_NULL:输出警告日志后返回null。

    • THROW_EXCEPTION:抛出异常,中断流程。

GetFileName

GetFileName用于从文件路径中提取文件名,返回类型为String

  • 方法

    evaluate(String filePath, String parseFailPolicy)
  • options参数说明

    parseFailPolicy:解析失败时的处理策略。String类型。默认值为"OUTPUT_NULL",取值如下:

    • OUTPUT_DEFAULT:静默返回null。

    • OUTPUT_NULL:静默返回null。

    • WARN_AND_NULL:输出警告日志后返回null。

    • THROW_EXCEPTION:抛出异常,中断流程。

使用示例

  1. 准备数据

    登录对象存储OSS控制台,并上传数据。本示例中使用测试数据如下:object_table_demo_files.zip

  2. 上传UDF jar包,创建UDF函数

    下载 Java UDF jar包:lakehouse-udf-1.0-SNAPSHOT.jar

    本示例使用odpscmd,其他Jar包上传方法参考UDF开发(Java)

    -- 进入odpscmd环境
    SET odps.sql.allow.namespace.schema=true;
    SET odps.namespace.schema=true;
    SET odps.sql.type.system.odps2=true;
    
    -- 创建object table
    DROP TABLE IF EXISTS udf_demo;
    CREATE OBJECT TABLE udf_demo 
    LOCATION 'oss://<endpoint>/<bucket>/path/to/files/'; -- location填上一步骤上传的文件的目录
    -- 刷新object table元信息
    ALTER TABLE udf_demo refresh metadata;
    
    -- 上传 udf jar 后创建functions
    add jar /path/to/lakehouse-udf-1.0-SNAPSHOT.jar;  -- 注意这里需要改为本地udf jar的绝对路径
    create function get_file_name as 'com.aliyun.odps.lakehouse.udf.GetFileName' using 'lakehouse-udf-1.0-SNAPSHOT.jar';
    create function get_file_media_type as 'com.aliyun.odps.lakehouse.udf.GetFileMediaType' using 'lakehouse-udf-1.0-SNAPSHOT.jar';
    create function get_file_content_type as 'com.aliyun.odps.lakehouse.udf.GetFileContentType' using 'lakehouse-udf-1.0-SNAPSHOT.jar';
    create function get_file_format as 'com.aliyun.odps.lakehouse.udf.GetFileFormat' using 'lakehouse-udf-1.0-SNAPSHOT.jar';
    create function get_file_meta as 'com.aliyun.odps.lakehouse.udf.GetFileMeta' using 'lakehouse-udf-1.0-SNAPSHOT.jar';
  3. object table中使用函数

    set odps.sql.allow.namespace.schema=true;
    set odps.namespace.schema=true;
    set odps.sql.type.system.odps2=true;
    
    -- 查询文件内容类型 & 文件媒体类型
    select 
      key, 
      get_file_content_type(key, "OUTPUT_DEFAULT"), 
      get_file_media_type(key, "OUTPUT_DEFAULT") 
    from udf_demo;
    -- 结果:
    +------------+------------+------------+
    | key        | _c1        | _c2        | 
    +------------+------------+------------+
    | lancePaper.pdf | application/pdf | application | 
    | sample.avi | video/x-msvideo | video      | 
    | sample.doc | application/msword | application | 
    | sample.gif | image/gif  | image      | 
    | sample.jpeg | image/jpeg | image      | 
    | sample.jpg | image/jpeg | image      | 
    | sample.mp3 | audio/mpeg | audio      | 
    | sample.mp4 | video/mp4  | video      | 
    | sample.png | image/png  | image      | 
    | sample.ppt | application/vnd.ms-powerpoint | application | 
    | sample.wav | audio/vnd.wave | audio      | 
    | sample.xls | application/vnd.ms-excel | application | 
    +------------+------------+------------+
    
    -- 查询文件格式&元数据 (假设文件名称中都有格式后缀, 例如 "xxx.pdf")
    select 
      key,
      get_file_format(key, 'OUTPUT_DEFAULT'), 
      get_file_meta(
        -- get_data_from_oss函数可以从oss上获取文件内容
        get_data_from_oss('three_tier_model.default.udf_demo', key), -- binary形式的文件内容
        get_file_format(key, 'OUTPUT_DEFAULT')  -- 文件类型, 如 pdf/mp3/avi/jpg 等
      )
    from udf_demo;

常见问题

使用UDF时遇到Java类冲突报错如何处理?

  • 错误信息

    java.lang.LinkageError: loader constraint violation: 
      when resolving overridden method "org.apache.xerces.jaxp.SAXParserImpl.parse(Lorg/xml/sax/InputSource;Lorg/xml/sax/helpers/DefaultHandler;)V" 
      the class loader (instance of com/aliyun/odps/udf/impl/utils/OdpsUserCodeLoaderFactory$ChildFirstLoader) of the current class, org/apache/xerces/jaxp/SAXParserImpl, 
      and its superclass loader (instance of <bootloader>), have different Class objects for the type org/xml/sax/helpers/DefaultHandler used in the signature
        at org.apache.xerces.jaxp.SAXParserFactoryImpl.newSAXParser(Unknown Source)
        at org.apache.tika.mime.MimeTypesReader.newSAXParser(MimeTypesReader.java:223)
  • 问题原因

    说明本文档提供的 UDF Jar 可能与您的项目空间中已存在的一些资源(如已存在的Java UDF)有类冲突。

  • 解决方案

    创建一个新的 schema,并在新的 schema 空间里上传 UDF Jar 后再创建 UDF 并使用。如果上述方案无效,可创建新的Project后再使用该功能。