KassieZ commented on code in PR #1383:
URL: https://github.com/apache/doris-website/pull/1383#discussion_r1851575890


##########
i18n/zh-CN/docusaurus-plugin-content-docs/current/query-data/udf/java-user-defined-function.md:
##########
@@ -139,16 +107,49 @@ public class AddOne extends UDF {
 }
 ```
 
-### UDAF
+2. 在Doris 中注册创建 Java-UDF 函数。 更多语法帮助可参阅 [CREATE 
FUNCTION](../../sql-manual/sql-statements/Data-Definition-Statements/Create/CREATE-FUNCTION.md).
 
-在使用 Java 代码编写 UDAF 时,有一些必须实现的函数 (标记 `required`) 和一个内部类 State,下面将以一个具体的实例来说明。
 
-**示例 1**
+```sql

Review Comment:
   有序下,需要缩近
   



##########
i18n/zh-CN/docusaurus-plugin-content-docs/current/query-data/udf/java-user-defined-function.md:
##########
@@ -349,87 +316,214 @@ public class MedianUDAF {
 
 ```
 
+
+2. 在Doris 中注册创建 Java-UADF 函数。 更多语法帮助可参阅 [CREATE 
FUNCTION](../../sql-manual/sql-statements/Data-Definition-Statements/Create/CREATE-FUNCTION.md).
+
+```sql

Review Comment:
   有序需要缩近



##########
i18n/zh-CN/docusaurus-plugin-content-docs/current/query-data/udf/java-user-defined-function.md:
##########
@@ -349,87 +316,214 @@ public class MedianUDAF {
 
 ```
 
+
+2. 在Doris 中注册创建 Java-UADF 函数。 更多语法帮助可参阅 [CREATE 
FUNCTION](../../sql-manual/sql-statements/Data-Definition-Statements/Create/CREATE-FUNCTION.md).
+
+```sql
+CREATE AGGREGATE FUNCTION simple_demo(INT) RETURNS INT PROPERTIES (
+    "file"="file:///pathTo/java-udaf.jar",
+    "symbol"="org.apache.doris.udf.SimpleDemo",
+    "always_nullable"="true",
+    "type"="JAVA_UDF"
+);
+```
+
+3. 使用 Java-UDAF, 可以分组聚合或者聚合全部结果:
+
+```sql
+select simple_demo(id) from test_table group by id;
++-----------------+
+| simple_demo(id) |
++-----------------+
+|               1 |
+|               6 |
++-----------------+
+```
+
+```sql
+select simple_demo(id) from test_table;
++-----------------+
+| simple_demo(id) |
++-----------------+
+|               7 |
++-----------------+
+```
+
+### Java-UDTF 实例介绍
+:::tip
+UDTF 自 Doris 3.0 版本开始支持
+:::
+
+1. 首先编写对应的Java UDTF 代码,打包生成JAR 包。
+UDTF 和 UDF 函数一样,需要用户自主实现一个 `evaluate` 方法, 但是 UDTF 函数的返回值必须是 Array 类型。
+
+```JAVA
+public class UDTFStringTest {
+    public ArrayList<String> evaluate(String value, String separator) {
+        if (value == null || separator == null) {
+            return null;
+        } else {
+            return new ArrayList<>(Arrays.asList(value.split(separator)));
+        }
+    }
+}
+```
+
+2. 在Doris 中注册创建 Java-UDTF 函数。 此时会注册两个UTDF 函数,另外一个是在函数名后面加上`_outer`后缀, 
其中带后缀`_outer` 的是针对结果为0行时的特殊处理,具体可查看[OUTER 
组合器](../../sql-manual/sql-functions/table-functions/explode-numbers-outer.md)。 
+更多语法帮助可参阅 [CREATE 
FUNCTION](../../sql-manual/sql-statements/Data-Definition-Statements/Create/CREATE-FUNCTION.md).
+
+```sql
+CREATE TABLES FUNCTION java-utdf(string, string) RETURNS array<string> 
PROPERTIES (
+    "file"="file:///pathTo/java-udaf.jar",
+    "symbol"="org.apache.doris.udf.demo.UDTFStringTest",
+    "always_nullable"="true",
+    "type"="JAVA_UDF"
+);
+```
+
+3. 使用 Java-UDTF, 在Doris 中使用UDTF 需要结合 Lateral View, 实现行转列的效果 :
+
+```sql
+select id, str, e1 from test_table lateral view java_utdf(str,',') tmp as e1;
++------+-------+------+
+| id   | str   | e1   |
++------+-------+------+
+|    1 | a,b,c | a    |
+|    1 | a,b,c | b    |
+|    1 | a,b,c | c    |
+|    6 | d,e   | d    |
+|    6 | d,e   | e    |
++------+-------+------+
+```
+
 ## 最佳实践
 
 ### Static 变量加载
 
 当前在 Doris 中,执行一个 UDF 函数,例如 `select udf(col) from table`, 每一个并发 Instance 会加载一次 
udf.jar 包,在该 instance 结束时卸载掉 udf.jar 包。

Review Comment:
   Instance 大小写一致



##########
i18n/zh-CN/docusaurus-plugin-content-docs/current/query-data/udf/java-user-defined-function.md:
##########
@@ -139,16 +107,49 @@ public class AddOne extends UDF {
 }
 ```
 
-### UDAF
+2. 在Doris 中注册创建 Java-UDF 函数。 更多语法帮助可参阅 [CREATE 
FUNCTION](../../sql-manual/sql-statements/Data-Definition-Statements/Create/CREATE-FUNCTION.md).
 
-在使用 Java 代码编写 UDAF 时,有一些必须实现的函数 (标记 `required`) 和一个内部类 State,下面将以一个具体的实例来说明。
 
-**示例 1**
+```sql
+CREATE FUNCTION java_udf_add_one(int) RETURNS int PROPERTIES (
+    "file"="file:///path/to/java-udf-demo-jar-with-dependencies.jar",
+    "symbol"="org.apache.doris.udf.AddOne",
+    "always_nullable"="true",
+    "type"="JAVA_UDF"
+);
+```
+
+3. 用户使用 UDF 必须拥有对应数据库的 `SELECT` 权限。
+UDF 的使用与普通的函数方式一致,唯一的区别在于,内置函数的作用域是全局的,而 UDF 的作用域是 DB 内部。
+
+    当链接 session 位于数据内部时,直接使用 UDF 名字会在当前 DB 内部查找对应的 UDF。否则用户需要显示的指定 UDF 
的数据库名字,例如 `dbName.funcName`。
+
+    使用UDF 查看注册成功的对应UDF 函数,可以使用[SHOW 
FUNCTIONS](../../sql-manual/sql-statements/Show-Statements/SHOW-FUNCTIONS.md) 
命令。
+
+``` sql
+select id,java_udf_add_one(id) from test_table;
++------+----------------------+
+| id   | java_udf_add_one(id) |
++------+----------------------+
+|    1 |                    2 |
+|    6 |                    7 |
++------+----------------------+
+```
 
-下面的 SimpleDemo 将实现一个类似的 SUM 的简单函数,输入参数 INT,输出参数是 INT。
+4. 当不再需要 UDF 函数时,可以通过下述命令来删除一个 UDF 函数,可以参考 [DROP 
FUNCTION](../../sql-manual/sql-statements/Data-Definition-Statements/Drop/DROP-FUNCTION.md)
+
+
+
+### Java-UDAF 实例介绍
+
+    在使用 Java 代码编写 UDAF 时,有一些必须实现的函数 (标记 required) 和一个内部类 State,下面将以具体的实例来说明。

Review Comment:
   这里不需要缩近
   



##########
i18n/zh-CN/docusaurus-plugin-content-docs/current/query-data/udf/java-user-defined-function.md:
##########
@@ -139,16 +107,49 @@ public class AddOne extends UDF {
 }
 ```
 
-### UDAF
+2. 在Doris 中注册创建 Java-UDF 函数。 更多语法帮助可参阅 [CREATE 
FUNCTION](../../sql-manual/sql-statements/Data-Definition-Statements/Create/CREATE-FUNCTION.md).
 
-在使用 Java 代码编写 UDAF 时,有一些必须实现的函数 (标记 `required`) 和一个内部类 State,下面将以一个具体的实例来说明。
 
-**示例 1**
+```sql
+CREATE FUNCTION java_udf_add_one(int) RETURNS int PROPERTIES (
+    "file"="file:///path/to/java-udf-demo-jar-with-dependencies.jar",
+    "symbol"="org.apache.doris.udf.AddOne",
+    "always_nullable"="true",
+    "type"="JAVA_UDF"
+);
+```
+
+3. 用户使用 UDF 必须拥有对应数据库的 `SELECT` 权限。
+UDF 的使用与普通的函数方式一致,唯一的区别在于,内置函数的作用域是全局的,而 UDF 的作用域是 DB 内部。
+
+    当链接 session 位于数据内部时,直接使用 UDF 名字会在当前 DB 内部查找对应的 UDF。否则用户需要显示的指定 UDF 
的数据库名字,例如 `dbName.funcName`。
+
+    使用UDF 查看注册成功的对应UDF 函数,可以使用[SHOW 
FUNCTIONS](../../sql-manual/sql-statements/Show-Statements/SHOW-FUNCTIONS.md) 
命令。
+
+``` sql
+select id,java_udf_add_one(id) from test_table;
++------+----------------------+
+| id   | java_udf_add_one(id) |
++------+----------------------+
+|    1 |                    2 |
+|    6 |                    7 |
++------+----------------------+
+```
 
-下面的 SimpleDemo 将实现一个类似的 SUM 的简单函数,输入参数 INT,输出参数是 INT。
+4. 当不再需要 UDF 函数时,可以通过下述命令来删除一个 UDF 函数,可以参考 [DROP 
FUNCTION](../../sql-manual/sql-statements/Data-Definition-Statements/Drop/DROP-FUNCTION.md)
+
+
+
+### Java-UDAF 实例介绍
+
+    在使用 Java 代码编写 UDAF 时,有一些必须实现的函数 (标记 required) 和一个内部类 State,下面将以具体的实例来说明。
+
+1. 首先编写对应的Java UDAF 代码,打包生成JAR 包。
+
+##### 示例1: SimpleDemo 将实现一个类似的 sum 的简单函数,输入参数 INT,输出参数是 INT.

Review Comment:
   层级过深,建议使用加粗或者 summary 元素,将示例折叠



##########
i18n/zh-CN/docusaurus-plugin-content-docs/current/query-data/udf/java-user-defined-function.md:
##########
@@ -349,87 +316,214 @@ public class MedianUDAF {
 
 ```
 
+
+2. 在Doris 中注册创建 Java-UADF 函数。 更多语法帮助可参阅 [CREATE 
FUNCTION](../../sql-manual/sql-statements/Data-Definition-Statements/Create/CREATE-FUNCTION.md).
+
+```sql
+CREATE AGGREGATE FUNCTION simple_demo(INT) RETURNS INT PROPERTIES (
+    "file"="file:///pathTo/java-udaf.jar",
+    "symbol"="org.apache.doris.udf.SimpleDemo",
+    "always_nullable"="true",
+    "type"="JAVA_UDF"
+);
+```
+
+3. 使用 Java-UDAF, 可以分组聚合或者聚合全部结果:
+
+```sql
+select simple_demo(id) from test_table group by id;
++-----------------+
+| simple_demo(id) |
++-----------------+
+|               1 |
+|               6 |
++-----------------+
+```
+
+```sql
+select simple_demo(id) from test_table;
++-----------------+
+| simple_demo(id) |
++-----------------+
+|               7 |
++-----------------+
+```
+
+### Java-UDTF 实例介绍
+:::tip
+UDTF 自 Doris 3.0 版本开始支持
+:::
+
+1. 首先编写对应的Java UDTF 代码,打包生成JAR 包。
+UDTF 和 UDF 函数一样,需要用户自主实现一个 `evaluate` 方法, 但是 UDTF 函数的返回值必须是 Array 类型。
+
+```JAVA
+public class UDTFStringTest {
+    public ArrayList<String> evaluate(String value, String separator) {
+        if (value == null || separator == null) {
+            return null;
+        } else {
+            return new ArrayList<>(Arrays.asList(value.split(separator)));
+        }
+    }
+}
+```
+
+2. 在Doris 中注册创建 Java-UDTF 函数。 此时会注册两个UTDF 函数,另外一个是在函数名后面加上`_outer`后缀, 
其中带后缀`_outer` 的是针对结果为0行时的特殊处理,具体可查看[OUTER 
组合器](../../sql-manual/sql-functions/table-functions/explode-numbers-outer.md)。 
+更多语法帮助可参阅 [CREATE 
FUNCTION](../../sql-manual/sql-statements/Data-Definition-Statements/Create/CREATE-FUNCTION.md).
+
+```sql
+CREATE TABLES FUNCTION java-utdf(string, string) RETURNS array<string> 
PROPERTIES (
+    "file"="file:///pathTo/java-udaf.jar",
+    "symbol"="org.apache.doris.udf.demo.UDTFStringTest",
+    "always_nullable"="true",
+    "type"="JAVA_UDF"
+);
+```
+
+3. 使用 Java-UDTF, 在Doris 中使用UDTF 需要结合 Lateral View, 实现行转列的效果 :
+
+```sql
+select id, str, e1 from test_table lateral view java_utdf(str,',') tmp as e1;
++------+-------+------+
+| id   | str   | e1   |
++------+-------+------+
+|    1 | a,b,c | a    |
+|    1 | a,b,c | b    |
+|    1 | a,b,c | c    |
+|    6 | d,e   | d    |
+|    6 | d,e   | e    |
++------+-------+------+
+```
+
 ## 最佳实践
 
 ### Static 变量加载
 
 当前在 Doris 中,执行一个 UDF 函数,例如 `select udf(col) from table`, 每一个并发 Instance 会加载一次 
udf.jar 包,在该 instance 结束时卸载掉 udf.jar 包。
 
 所以当 udf.jar 文件中需要加载一个几百 MB 的文件时,会因为并发的原因,使得占据的内存急剧增大,容易 OOM。
+或者想使用一个连接池时,这样无法做到仅在static 区域初始化一次。
 
-解决方法是可以将资源加载代码拆分开,单独生成一个 jar 包文件,其他包直接引用该资源 jar 包。 
+这里提供两个解决方案,其中方案二需要Doris 版本在branch-3.0 以上才行。
 
-假设已经拆分为了 DictLibrary 和 FunctionUdf 两个文件。
+#### 解决方案1: 
+是可以将资源加载代码拆分开,单独生成一个 jar 包文件,然后其他包直接引用该资源 jar 包。 
 
-1. 单独编译 DictLibrary 文件,使其生成一个独立的 jar 包,这样可以得到一个资源文件 DictLibrary.jar: 
-
-    ```shell
-    javac   ./DictLibrary.java
-    jar -cf ./DictLibrary.jar ./DictLibrary.class
-    ```
+假设已经将代码拆分为了 DictLibrary 和 FunctionUdf 两个文件。
 
-    ```java
-    public class DictLibrary {
-        private static HashMap<String, String> res = new HashMap<>();
-
-        static {
-            // suppose we built this dictionary from a certain local file.
-            res.put("key1", "value1");
-            res.put("key2", "value2");
-            res.put("key3", "value3");
-            res.put("0", "value4");
-            res.put("1", "value5");
-            res.put("2", "value6");
-        }
+```java
+public class DictLibrary {
+    private static HashMap<String, String> res = new HashMap<>();
+
+    static {
+        // suppose we built this dictionary from a certain local file.
+        res.put("key1", "value1");
+        res.put("key2", "value2");
+        res.put("key3", "value3");
+        res.put("0", "value4");
+        res.put("1", "value5");
+        res.put("2", "value6");
+    }
 
-        public static String evaluate(String key) {
-            if (key == null) {
-                return null;
-            }
-            return res.get(key);
+    public static String evaluate(String key) {
+        if (key == null) {
+            return null;
         }
+        return res.get(key);
     }
-    ```
+}
+```
 
-    ```java
-    public class FunctionUdf {
-        public String evaluate(String key) {
-            String value = DictLibrary.evaluate(key);
-            return value;
-        }
+```java
+public class FunctionUdf {
+    public String evaluate(String key) {
+        String value = DictLibrary.evaluate(key);
+        return value;
     }
+}
+```
+
+1. 单独编译 DictLibrary 文件,使其生成一个独立的 jar 包,这样可以得到一个资源文件包 DictLibrary.jar: 
+
+    ```shell
+    javac   ./DictLibrary.java
+    jar -cf ./DictLibrary.jar ./DictLibrary.class
     ```
 
-2. 编译 FunctionUdf 文件,可以直接引用上一步的到的资源包,这样可以得到 UDF 的 FunctionUdf.jar 包。
+2. 编译 FunctionUdf 文件,需要引用上一步的到的资源包最为库使用,这样打包后可以得到 UDF 的 FunctionUdf.jar 包。
 
     ```shell
     javac -cp ./DictLibrary.jar  ./FunctionUdf.java
     jar  -cvf ./FunctionUdf.jar  ./FunctionUdf.class
     ```
 
-3. 经过上面两步之后,会得到两个 jar 包,由于想让资源 jar 包被所有的并发引用,所以需要将它放到指定路径 `fe/custom_lib` 和 
`be/custom_lib` 下面,服务重启之后就可以随着 JVM 的启动加载进来。
+3. 由于想让资源 jar 包被所有的并发引用,所以想让它被JVM 直接夹在,可以将它放到指定路径 `be/custom_lib` 下面,BE 
服务重启之后就可以随着 JVM 的启动加载进来,因此都会随着服务启动而加载,停止而释放。
 
-4. 最后利用 `CREATE FUNCTION` 语句创建一个 UDF 函数
+4. 最后利用 `CREATE FUNCTION` 语句创建一个 UDF 函数, 这样每次卸载仅是FunctionUdf.jar。
 
    ```sql
    CREATE FUNCTION java_udf_dict(string) RETURNS string PROPERTIES (
+    "file"="file:///pathTo/FunctionUdf.jar",
     "symbol"="org.apache.doris.udf.FunctionUdf",
     "always_nullable"="true",
     "type"="JAVA_UDF"
    );
    ```
 
-使用该加载方式时,FunctionUdf.jar 和 DictLibrary.jar 都在 FE 和 BE 的 custom_lib 
路径下,因此都会随着服务启动而加载,停止而释放,不再需要指定 File 的路径。
+#### 解决方案2: 
 
-也可以使用 file:/// 方式自定义 FunctionUdf.jar 的路径,但是 DictLibrary.jar 只能放在 custom_lib 下。
+BE 全局缓存jar 包,自定义过期淘汰时间,在create function 时增加两个属性字段,其中
+static_load: 用于定义是否使用静态cache 加载的方式,

Review Comment:
   这里需要无序或者有序,或者成段



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to