ClickHouse Java多参UDF

这篇具有很好参考价值的文章主要介绍了ClickHouse Java多参UDF。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、环境版本

环境 版本
docker clickhouse 22.3.10.22
docker pull clickhouse/clickhouse-server:22.3.10.22

二、XML配置

2.1 配置文件

# 创建udf配置文件
vim /etc/clickhouse-server/demo_function.xml
<functions>
    <function>
        <type>executable</type>
        <!--udf函数名称-->
        <name>demo_clickhouse_udf</name>
        <!--返回值类型-->
        <return_type>String</return_type>
        <!--返回值名称,默认值为result-->
        <!--当format为JSONEachRow时,取返回json中的result字段-->
        <return_name>result</return_name>
        <!--输入参数-->
        <!--当format为JSONEachRow时,入参为{"argument_1": 入参1,"argument_2": 入参2}-->
        <argument>
            <type>UInt64</type>
            <name>argument_1</name>
        </argument>
        <argument>
            <type>UInt64</type>
            <name>argument_2</name>
        </argument>
        <!--input和output的数据格式化方式-->
        <format>JSONEachRow</format>
        <!--command运行方式,0为指定命令,1为默认方式-->
        <execute_direct>0</execute_direct>
        <!--command命令,最好带上根目录,避免出现函数不支持问题-->
        <command>/usr/bin/java -jar /var/lib/clickhouse/user_scripts/demo_clickhouse_udf-1.0-SNAPSHOT-jar-with-dependencies.jar</command>
    </function>
</functions>

三、Java代码

新建Maven项目

3.1 pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>demo_clickhouse_udf</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.10.1</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>3.3.0</version>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>org.example.Main</mainClass>
                        </manifest>
                    </archive>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
                <executions>
                    <execution>
                        <id>assemble-all</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

3.2 Main.java

package org.example;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.annotations.Expose;
import java.io.BufferedInputStream;
import java.io.DataInputStream;


public class Main {
    public static void main(String[] args) {
        try {
            DataInputStream in = new DataInputStream(new BufferedInputStream(System.in));
            String s;

            // 逐行读取数据
            while ((s = in.readLine()).length() != 0) {
                // 获取输入参数
                Gson gson = new Gson();
                JsonElement jsonElement = gson.fromJson(s, JsonElement.class);
                JsonObject jsonObject = jsonElement.getAsJsonObject();
                String argument_1 = jsonObject.get("argument_1").getAsString();
                String argument_2 = jsonObject.get("argument_2").getAsString();
                // 封装输出结果
                String resultStr = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create().toJson(new Demo(argument_1, argument_2));
                System.out.println(gson.toJson(new Result(resultStr)));
            }
            System.out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 返回对象
     */
    public static class Demo{
        @Expose
        private String param1;

        @Expose
        private String param2;

        public Demo(String param1, String param2){
            this.param1 = param1;
            this.param2 = param2;
        }

        public String getParam1() {
            return param1;
        }

        public void setParam1(String param1) {
            this.param1 = param1;
        }

        public String getParam2() {
            return param2;
        }

        public void setParam2(String param2) {
            this.param2 = param2;
        }
    }

    /**
     * 返回结果
     * 返回值名称必须跟xml文件中的return_name一致
     * xml文件return_name默认值result
     * 即: 返回结果为 "{'result': {...}, 'other': {...}, ...}"时
     * 返回值ClickHouse调用函数返回值只去result的值
     */
    public static class Result {
        private String result;

        public String getResult() {
            return result;
        }

        public void setResult(String result) {
            this.result = result;
        }

        public Result(String result){
            this.result = result;
        }
    }
}

3.3 打包将jar包复制到ClickHouse中

docker cp 路径/demo_clickhouse_udf-1.0-SNAPSHOT-jar-with-dependencies.jar 容器id:/var/lib/clickhouse/user_scripts/demo_clickhouse_udf-1.0-SNAPSHOT-jar-with-dependencies.jar

3.4 SQL验证

SYSTEM RELOAD FUNCTIONS; # 刷新函数
SELECT * FROM system.functions WHERE name = 'demo_clickhouse_udf'; # 查询刚添加的udf函数
select demo_clickhouse_udf(1,2)

返回

{"param1":"1","param2":"2"}

3.5 Json字典,数据展开

返回

{"param1":"1","param2":"2"}

数据展开

select
    JSON_VALUE(result, '$.param1') as param1,
    JSON_VALUE(result, '$.param2') as param2
from(
    select demo_clickhouse_udf(1,2) as result
) t1;

3.6 Json数组,数据展开

java例程

	public static void main(String[] args) {
        try {
            DataInputStream in = new DataInputStream(new BufferedInputStream(System.in));
            String s;

            // 逐行读取数据
            while ((s = in.readLine()).length() != 0) {
                // 获取输入参数
                Gson gson = new Gson();
                JsonElement jsonElement = gson.fromJson(s, JsonElement.class);
                JsonObject jsonObject = jsonElement.getAsJsonObject();
                String argument_1 = jsonObject.get("argument_1").getAsString();
                String argument_2 = jsonObject.get("argument_2").getAsString();
                List<Demo> demoList = new ArrayList<>();
                demoList.add(new Demo(argument_1, argument_2));
                demoList.add(new Demo("3", "4"));
                demoList.add(new Demo("5", "6"));
                // 封装输出结果
                String resultStr = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create().toJson(demoList);
                System.out.println(gson.toJson(new Result(resultStr)));
            }
            System.out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

返回

[{"param1":"1","param2":"2"},{"param1":"3","param2":"4"},{"param1":"5","param2":"6"}]

数据展开

select
    JSONExtractString(arrayElement, 'param1') as param1,
    JSONExtractString(arrayElement, 'param2') as param2
from(
    select demo_clickhouse_udf(1,2) as result
) t1
ARRAY JOIN JSONExtractArrayRaw(result) AS arrayElement;

四、异常问题

4.1 UNKNOWN_FUNCTION

xml文件名称需以function.xml结尾,其它则会添加失败,找不到函数。

# 运行sql
SYSTEM RELOAD FUNCTIONS; # 刷新函数
SELECT * FROM system.functions WHERE name = 'demo_clickhouse_udf'; # 查询刚添加的udf函数
# 报错
Code: 46. DB::Exception: Unknown function demo_clickhouse_udf: While processing demo_clickhouse_udf(1, 2). (UNKNOWN_FUNCTION) (version 22.3.10.22 (official build))

4.2 UNSUPPORTED_METHOD

1.execute_direct需为0

<execute_direct>0</execute_direct>

2.command需带上根目录,如/usr/bin/java

<command>/usr/bin/java -jar /var/lib/clickhouse/user_scripts/demo_clickhouse_udf-1.0-SNAPSHOT-jar-with-dependencies.jar</command>

3.没有安装java等语言环境

4.没有命令或脚本权限

5.版本不支持,如:22.2.3.5

# 报错
Code: 1. DB::Exception: Executable file /usr/bin/java does not exist inside user scripts folder /var/lib/clickhouse/user_scripts/: While processing demo_clickhouse_udf(1, 2). (UNSUPPORTED_METHOD) (version 22.3.10.22 (official build))

4.3 CANNOT_PARSE_QUOTED_STRING

返回字符串格式不对,没有用result封装成json

// 错误的java示例
System.out.println("{'result':1}");
# 报错
Code: 26. DB::ParsingException: Cannot parse JSON string: expected opening quote: While executing ParallelParsingBlockInputFormat: While executing ShellCommandSource: While processing demo_clickhouse_udf(1, 2): (at row 1) . (CANNOT_PARSE_QUOTED_STRING) (version 22.3.10.22 (official build))

五、参考借鉴

ClickHouse Doc
Github Issues文章来源地址https://www.toymoban.com/news/detail-738220.html

到了这里,关于ClickHouse Java多参UDF的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ClickHouse--11--ClickHouse API操作

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 JDBC–01–简介 ClickHouse java代码 SparkCore 写入 ClickHouse,可以直接采用写入方式。下面案例是使用 SparkSQL 将结果存入 ClickHouse对应的表中。在 ClickHouse 中需要预先创建好对应的结果表 可以通过 Flink 原生

    2024年02月21日
    浏览(39)
  • 基于clickhouse keeper搭建clickhouse集群

    主机名 IP my-db01 192.168.1.214 my-db02 192.168.1.215 my-db03 192.168.1.216 hosts设置 使用 admin 用户安装: 添加官方镜像 安装 clickhouse-server和clickhouse-client 版本信息: 操作系统:CentOS Linux release 7.9.2009 (Core) systemd:219 clickhouse-client:23.2.4.12-1.x86_64 clickhouse-server:23.2.4.12-1.x86_64 clickhouse-commo

    2024年02月12日
    浏览(45)
  • clickhouse 系列2:clickhouse 离线安装

    https://download.csdn.net/download/shangjg03/88353547 /etc/clickhouse-server : 服务端的配置文件目录,包括全局配置config.xml 和用户配置users.xml。 /var/lib/clickhouse : 默认的数据存储目

    2024年02月11日
    浏览(40)
  • 探索ClickHouse——连接Kafka和Clickhouse

    可以从https://downloads.apache.org/kafka/下找到希望安装的版本。需要注意的是,不要下载路径包含src的包,否则会报“Classpath is empty”之类的错误。 配置kafka 将下面这行加入文件的末尾 同时修改log的路径 创建zookeeper service 将下面内容填入上述文件中 创建kafka service 将下面内容填

    2024年02月07日
    浏览(50)
  • ClickHouse基础知识(一):ClickHouse 入门

    ClickHouse 是俄罗斯的 Yandex 于 2016 年开源的 列式存储数据库 (DBMS),使用 C++ 语言编写,主要用于 在线分析处理查询(OLAP) ,能够使用 SQL 查询实时生成分析数据报告。 以下面的表为例: 1)采用行式存储时,数据在磁盘上的组织结构为: 好处是想查某个人所有的属性时,

    2024年02月03日
    浏览(41)
  • ClickHouse进阶(十七):clickhouse优化-写出查询优化

    进入正文前,感谢宝子们订阅专题、点赞、评论、收藏!关注IT贫道,获取高质量博客内容! 🏡个人主页:含各种IT体系技术,IT贫道_大数据OLAP体系技术栈,Apache Doris,Kerberos安全认证-CSDN博客 📌订阅:拥抱独家专题,你的订阅将点燃我的创作热情! 👍点赞:赞同优秀创作,你

    2024年02月07日
    浏览(57)
  • 【Flink】【ClickHouse】写入流式数据到ClickHouse

    Flink 安装的教程就不在这里赘叙了,可以看一下以前的文章,这篇文章主要是把流式数据写入的OLAP(ClickHouse)中作查询分析 Flink 1.13.2, ClickHouse 22.1.3.7 这里直接使用docker安装,没有安装的同学可以使用homebreak来安装,执行下面的命令即可( 已经安装了docker的可以忽略 ) 四指

    2024年02月03日
    浏览(44)
  • ClickHouse进阶(七):Clickhouse数据查询-1

    进入正文前,感谢宝子们订阅专题、点赞、评论、收藏!关注IT贫道,获取高质量博客内容! 🏡个人主页:含各种IT体系技术,IT贫道_Apache Doris,大数据OLAP体系技术栈,Kerberos安全认证-CSDN博客 📌订阅:拥抱独家专题,你的订阅将点燃我的创作热情! 👍点赞:赞同优秀创作,你

    2024年02月10日
    浏览(48)
  • ClickHouse学习笔记(六):ClickHouse物化视图使用

    ClickHouse 的物化视图是一种查询结果的持久化,它的存在是为了带来查询效率的提升。用户使用物化视图时跟普通的表没有太大区别,其实它就是一张逻辑表,也像是一张时刻在预计算的表,创建的过程它是用了一个特殊引擎,加上后来 as select,就是 create 一个 table as select

    2024年01月17日
    浏览(42)
  • ClickHouse10-ClickHouse中Kafka表引擎

    Kafka表引擎也是一种常见的表引擎,在很多大数据量的场景下,会从源通过Kafka将数据输送到ClickHouse,Kafka作为输送的方式,ClickHouse作为存储引擎与查询引擎,大数据量的数据可以得到快速的、高压缩的存储。 Kafka大家肯定不陌生: 它可以用于发布和订阅数据流,是常见的队

    2024年04月25日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包