blob: 2a36cbfe578b5e4bcfb3b5b9df417972414d4fc6 [file] [log] [blame]
<!doctype html>
<html lang="zh-CN" data-theme="light">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<meta name="generator" content="VuePress 2.0.0-rc.9" />
<meta name="theme" content="VuePress Theme Hope 2.0.0-rc.34" />
<style>
html {
background: var(--bg-color, #fff);
}
html[data-theme="dark"] {
background: var(--bg-color, #1d1e1f);
}
body {
background: var(--bg-color);
}
</style>
<script>
const userMode = localStorage.getItem("vuepress-theme-hope-scheme");
const systemDarkMode =
window.matchMedia &&
window.matchMedia("(prefers-color-scheme: dark)").matches;
if (userMode === "dark" || (userMode !== "light" && systemDarkMode)) {
document.documentElement.setAttribute("data-theme", "dark");
}
</script>
<link rel="alternate" hreflang="en-us" href="https://iotdb.apache.org/UserGuide/V0.13.x/Process-Data/UDF-User-Defined-Function.html"><meta property="og:url" content="https://iotdb.apache.org/zh/UserGuide/V0.13.x/Process-Data/UDF-User-Defined-Function.html"><meta property="og:site_name" content="IoTDB Website"><meta property="og:title" content="数据处理"><meta property="og:description" content="数据处理 用户定义函数 (UDF) UDF(User Defined Function)即用户自定义函数。IoTDB 提供多种内建函数来满足您的计算需求,同时您还可以通过创建自定义函数来满足更多的计算需求。 根据此文档,您将会很快学会 UDF 的编写、注册、使用等操作。 UDF 类型 IoTDB 支持两种类型的 UDF 函数,如下表所示。 UDF 依赖..."><meta property="og:type" content="article"><meta property="og:locale" content="zh-CN"><meta property="og:locale:alternate" content="en-US"><meta property="og:updated_time" content="2023-07-10T03:11:17.000Z"><meta property="article:modified_time" content="2023-07-10T03:11:17.000Z"><script type="application/ld+json">{"@context":"https://schema.org","@type":"Article","headline":"数据处理","image":[""],"dateModified":"2023-07-10T03:11:17.000Z","author":[]}</script><link rel="icon" href="/favicon.ico"><meta name="Description" content="Apache IoTDB: Time Series Database for IoT"><meta name="Keywords" content="TSDB, time series, time series database, IoTDB, IoT database, IoT data management,时序数据库, 时间序列管理, IoTDB, 物联网数据库, 实时数据库, 物联网数据管理, 物联网数据"><meta name="baidu-site-verification" content="wfKETzB3OT"><meta name="google-site-verification" content="mZWAoRY0yj_HAr-s47zHCGHzx5Ju-RVm5wDbPnwQYFo"><script type="text/javascript">
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(["setDoNotTrack", true]);
_paq.push(["disableCookies"]);
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="https://analytics.apache.org/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '56']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script><title>数据处理 | IoTDB Website</title><meta name="description" content="数据处理 用户定义函数 (UDF) UDF(User Defined Function)即用户自定义函数。IoTDB 提供多种内建函数来满足您的计算需求,同时您还可以通过创建自定义函数来满足更多的计算需求。 根据此文档,您将会很快学会 UDF 的编写、注册、使用等操作。 UDF 类型 IoTDB 支持两种类型的 UDF 函数,如下表所示。 UDF 依赖...">
<link rel="preload" href="/assets/style-DnEHAOmf.css" as="style"><link rel="stylesheet" href="/assets/style-DnEHAOmf.css">
<link rel="modulepreload" href="/assets/app-DrPcRZG6.js"><link rel="modulepreload" href="/assets/UDF-User-Defined-Function.html-wcY1xCKe.js">
</head>
<body>
<div id="app"><!--[--><!--[--><!--[--><span tabindex="-1"></span><a href="#main-content" class="vp-skip-link sr-only">跳至主要內容</a><!--]--><!--[--><div class="theme-container has-toc"><!--[--><header id="navbar" class="vp-navbar hide-icon"><div class="vp-navbar-start"><button type="button" class="vp-toggle-sidebar-button" title="Toggle Sidebar"><span class="icon"></span></button><!--[--><!----><!--]--><!--[--><a class="route-link vp-brand" href="/zh/"><img class="vp-nav-logo" src="/logo.png" alt><!----><span class="vp-site-name hide-in-pad">IoTDB Website</span></a><!--]--><!--[--><!----><!--]--></div><div class="vp-navbar-center"><!--[--><!----><!--]--><!--[--><!--]--><!--[--><!----><!--]--></div><div class="vp-navbar-end"><!--[--><!----><!--]--><!--[--><!--[--><div id="docsearch-container" style="display:none;"></div><div><button type="button" class="DocSearch DocSearch-Button" aria-label="搜索文档"><span class="DocSearch-Button-Container"><svg width="20" height="20" class="DocSearch-Search-Icon" viewBox="0 0 20 20"><path d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path></svg><span class="DocSearch-Button-Placeholder">搜索文档</span></span><span class="DocSearch-Button-Keys"><kbd class="DocSearch-Button-Key"><svg width="15" height="15" class="DocSearch-Control-Key-Icon"><path d="M4.505 4.496h2M5.505 5.496v5M8.216 4.496l.055 5.993M10 7.5c.333.333.5.667.5 1v2M12.326 4.5v5.996M8.384 4.496c1.674 0 2.116 0 2.116 1.5s-.442 1.5-2.116 1.5M3.205 9.303c-.09.448-.277 1.21-1.241 1.203C1 10.5.5 9.513.5 8V7c0-1.57.5-2.5 1.464-2.494.964.006 1.134.598 1.24 1.342M12.553 10.5h1.953" stroke-width="1.2" stroke="currentColor" fill="none" stroke-linecap="square"></path></svg></kbd><kbd class="DocSearch-Button-Key">K</kbd></span></button></div><!--]--><nav class="vp-nav-links"><div class="vp-nav-item hide-in-mobile"><div class="dropdown-wrapper"><button type="button" class="dropdown-title" aria-label="文档"><span class="title"><!---->文档</span><span class="arrow"></span><ul class="nav-dropdown"><li class="dropdown-item"><a class="route-link nav-link" href="/zh/UserGuide/latest/QuickStart/QuickStart.html" aria-label="v1.3.x"><!---->v1.3.x<!----></a></li><li class="dropdown-item"><a class="route-link nav-link" href="/zh/UserGuide/V1.2.x/QuickStart/QuickStart.html" aria-label="v1.2.x"><!---->v1.2.x<!----></a></li><li class="dropdown-item"><a class="route-link nav-link" href="/zh/UserGuide/V1.1.x/QuickStart/QuickStart.html" aria-label="v1.1.x"><!---->v1.1.x<!----></a></li><li class="dropdown-item"><a class="route-link nav-link" href="/zh/UserGuide/V1.0.x/QuickStart/QuickStart.html" aria-label="v1.0.x"><!---->v1.0.x<!----></a></li><li class="dropdown-item"><a class="route-link nav-link" href="/zh/UserGuide/V0.13.x/QuickStart/QuickStart.html" aria-label="v0.13.x"><!---->v0.13.x<!----></a></li></ul></button></div></div><div class="vp-nav-item hide-in-mobile"><a href="https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=177051872" rel="noopener noreferrer" target="_blank" aria-label="系统设计" class="nav-link"><!---->系统设计<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span><!----></a></div><div class="vp-nav-item hide-in-mobile"><a class="route-link nav-link" href="/zh/Download/" aria-label="下载"><!---->下载<!----></a></div><div class="vp-nav-item hide-in-mobile"><div class="dropdown-wrapper"><button type="button" class="dropdown-title" aria-label="社区"><span class="title"><!---->社区</span><span class="arrow"></span><ul class="nav-dropdown"><li class="dropdown-item"><a class="route-link nav-link" href="/zh/Community/About.html" aria-label="关于社区"><!---->关于社区<!----></a></li><li class="dropdown-item"><a class="route-link nav-link" href="/zh/Community/Development-Guide.html" aria-label="贡献指南"><!---->贡献指南<!----></a></li><li class="dropdown-item"><a class="route-link nav-link" href="/zh/Community/Powered-By.html" aria-label="社区伙伴"><!---->社区伙伴<!----></a></li><li class="dropdown-item"><a class="route-link nav-link" href="/zh/Community/Feedback.html" aria-label="交流与反馈"><!---->交流与反馈<!----></a></li><li class="dropdown-item"><a class="route-link nav-link" href="/zh/Community/Materials.html" aria-label="活动与报告"><!---->活动与报告<!----></a></li><li class="dropdown-item"><a class="route-link nav-link" href="/zh/Community/Community-Project-Committers.html" aria-label="Commiters"><!---->Commiters<!----></a></li></ul></button></div></div><div class="vp-nav-item hide-in-mobile"><div class="dropdown-wrapper"><button type="button" class="dropdown-title" aria-label="ASF"><span class="title"><!---->ASF</span><span class="arrow"></span><ul class="nav-dropdown"><li class="dropdown-item"><a href="https://www.apache.org/" rel="noopener noreferrer" target="_blank" aria-label="基金会" class="nav-link"><!---->基金会<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span><!----></a></li><li class="dropdown-item"><a href="https://www.apache.org/licenses/" rel="noopener noreferrer" target="_blank" aria-label="许可证" class="nav-link"><!---->许可证<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span><!----></a></li><li class="dropdown-item"><a href="https://www.apache.org/security/" rel="noopener noreferrer" target="_blank" aria-label="安全" class="nav-link"><!---->安全<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span><!----></a></li><li class="dropdown-item"><a href="https://www.apache.org/foundation/sponsorship.html" rel="noopener noreferrer" target="_blank" aria-label="赞助" class="nav-link"><!---->赞助<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span><!----></a></li><li class="dropdown-item"><a href="https://www.apache.org/foundation/thanks.html" rel="noopener noreferrer" target="_blank" aria-label="致谢" class="nav-link"><!---->致谢<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span><!----></a></li><li class="dropdown-item"><a href="https://www.apache.org/events/current-event" rel="noopener noreferrer" target="_blank" aria-label="活动" class="nav-link"><!---->活动<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span><!----></a></li><li class="dropdown-item"><a href="https://privacy.apache.org/policies/privacy-policy-public.html" rel="noopener noreferrer" target="_blank" aria-label="隐私" class="nav-link"><!---->隐私<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span><!----></a></li></ul></button></div></div></nav><div class="vp-nav-item"><div class="dropdown-wrapper"><button type="button" class="dropdown-title" aria-label="选择语言"><!--[--><svg xmlns="http://www.w3.org/2000/svg" class="icon i18n-icon" viewBox="0 0 1024 1024" fill="currentColor" aria-label="i18n icon" style="width:1rem;height:1rem;vertical-align:middle;"><path d="M379.392 460.8 494.08 575.488l-42.496 102.4L307.2 532.48 138.24 701.44l-71.68-72.704L234.496 460.8l-45.056-45.056c-27.136-27.136-51.2-66.56-66.56-108.544h112.64c7.68 14.336 16.896 27.136 26.112 35.84l45.568 46.08 45.056-45.056C382.976 312.32 409.6 247.808 409.6 204.8H0V102.4h256V0h102.4v102.4h256v102.4H512c0 70.144-37.888 161.28-87.04 210.944L378.88 460.8zM576 870.4 512 1024H409.6l256-614.4H768l256 614.4H921.6l-64-153.6H576zM618.496 768h196.608L716.8 532.48 618.496 768z"></path></svg><!--]--><span class="arrow"></span><ul class="nav-dropdown"><li class="dropdown-item"><a class="route-link nav-link" href="/UserGuide/V0.13.x/Process-Data/UDF-User-Defined-Function.html" aria-label="English"><!---->English<!----></a></li><li class="dropdown-item"><a class="route-link nav-link active" href="/zh/UserGuide/V0.13.x/Process-Data/UDF-User-Defined-Function.html" aria-label="简体中文"><!---->简体中文<!----></a></li></ul></button></div></div><div class="vp-nav-item hide-in-mobile"><button type="button" id="appearance-switch"><svg xmlns="http://www.w3.org/2000/svg" class="icon auto-icon" viewBox="0 0 1024 1024" fill="currentColor" aria-label="auto icon" style="display:none;"><path d="M512 992C246.92 992 32 777.08 32 512S246.92 32 512 32s480 214.92 480 480-214.92 480-480 480zm0-840c-198.78 0-360 161.22-360 360 0 198.84 161.22 360 360 360s360-161.16 360-360c0-198.78-161.22-360-360-360zm0 660V212c165.72 0 300 134.34 300 300 0 165.72-134.28 300-300 300z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" class="icon dark-icon" viewBox="0 0 1024 1024" fill="currentColor" aria-label="dark icon" style="display:none;"><path d="M524.8 938.667h-4.267a439.893 439.893 0 0 1-313.173-134.4 446.293 446.293 0 0 1-11.093-597.334A432.213 432.213 0 0 1 366.933 90.027a42.667 42.667 0 0 1 45.227 9.386 42.667 42.667 0 0 1 10.24 42.667 358.4 358.4 0 0 0 82.773 375.893 361.387 361.387 0 0 0 376.747 82.774 42.667 42.667 0 0 1 54.187 55.04 433.493 433.493 0 0 1-99.84 154.88 438.613 438.613 0 0 1-311.467 128z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" class="icon light-icon" viewBox="0 0 1024 1024" fill="currentColor" aria-label="light icon" style="display:block;"><path d="M952 552h-80a40 40 0 0 1 0-80h80a40 40 0 0 1 0 80zM801.88 280.08a41 41 0 0 1-57.96-57.96l57.96-58a41.04 41.04 0 0 1 58 58l-58 57.96zM512 752a240 240 0 1 1 0-480 240 240 0 0 1 0 480zm0-560a40 40 0 0 1-40-40V72a40 40 0 0 1 80 0v80a40 40 0 0 1-40 40zm-289.88 88.08-58-57.96a41.04 41.04 0 0 1 58-58l57.96 58a41 41 0 0 1-57.96 57.96zM192 512a40 40 0 0 1-40 40H72a40 40 0 0 1 0-80h80a40 40 0 0 1 40 40zm30.12 231.92a41 41 0 0 1 57.96 57.96l-57.96 58a41.04 41.04 0 0 1-58-58l58-57.96zM512 832a40 40 0 0 1 40 40v80a40 40 0 0 1-80 0v-80a40 40 0 0 1 40-40zm289.88-88.08 58 57.96a41.04 41.04 0 0 1-58 58l-57.96-58a41 41 0 0 1 57.96-57.96z"></path></svg></button></div><div class="vp-nav-item vp-action"><a class="vp-action-link" href="https://github.com/apache/iotdb" target="_blank" rel="noopener noreferrer" aria-label="GitHub"><svg xmlns="http://www.w3.org/2000/svg" class="icon github-icon" viewBox="0 0 1024 1024" fill="currentColor" aria-label="github icon" style="width:1.25rem;height:1.25rem;vertical-align:middle;"><path d="M511.957 21.333C241.024 21.333 21.333 240.981 21.333 512c0 216.832 140.544 400.725 335.574 465.664 24.49 4.395 32.256-10.07 32.256-23.083 0-11.69.256-44.245 0-85.205-136.448 29.61-164.736-64.64-164.736-64.64-22.315-56.704-54.4-71.765-54.4-71.765-44.587-30.464 3.285-29.824 3.285-29.824 49.195 3.413 75.179 50.517 75.179 50.517 43.776 75.008 114.816 53.333 142.762 40.79 4.523-31.66 17.152-53.377 31.19-65.537-108.971-12.458-223.488-54.485-223.488-242.602 0-53.547 19.114-97.323 50.517-131.67-5.035-12.33-21.93-62.293 4.779-129.834 0 0 41.258-13.184 134.912 50.346a469.803 469.803 0 0 1 122.88-16.554c41.642.213 83.626 5.632 122.88 16.554 93.653-63.488 134.784-50.346 134.784-50.346 26.752 67.541 9.898 117.504 4.864 129.834 31.402 34.347 50.474 78.123 50.474 131.67 0 188.586-114.73 230.016-224.042 242.09 17.578 15.232 33.578 44.672 33.578 90.454v135.85c0 13.142 7.936 27.606 32.854 22.87C862.25 912.597 1002.667 728.747 1002.667 512c0-271.019-219.648-490.667-490.71-490.667z"></path></svg></a></div><!--]--><!--[--><!----><!--]--><button type="button" class="vp-toggle-navbar-button" aria-label="Toggle Navbar" aria-expanded="false" aria-controls="nav-screen"><span><span class="vp-top"></span><span class="vp-middle"></span><span class="vp-bottom"></span></span></button></div></header><!----><!--]--><!----><div class="toggle-sidebar-wrapper"><span class="arrow start"></span></div><aside id="sidebar" class="vp-sidebar"><!--[--><!----><!--]--><ul class="vp-sidebar-links"><li><section class="vp-sidebar-group"><p class="vp-sidebar-header"><!----><span class="vp-sidebar-title">IoTDB用户手册 (V0.13.x)</span><!----></p><ul class="vp-sidebar-links"></ul></section></li><li><section class="vp-sidebar-group"><button class="vp-sidebar-header clickable" type="button"><!----><span class="vp-sidebar-title">IoTDB简介</span><span class="vp-arrow end"></span></button><!----></section></li><li><section class="vp-sidebar-group"><button class="vp-sidebar-header clickable" type="button"><!----><span class="vp-sidebar-title">快速上手</span><span class="vp-arrow end"></span></button><!----></section></li><li><section class="vp-sidebar-group"><button class="vp-sidebar-header clickable" type="button"><!----><span class="vp-sidebar-title">数据模式与概念</span><span class="vp-arrow end"></span></button><!----></section></li><li><section class="vp-sidebar-group"><button class="vp-sidebar-header clickable" type="button"><!----><span class="vp-sidebar-title">语法约定</span><span class="vp-arrow end"></span></button><!----></section></li><li><section class="vp-sidebar-group"><button class="vp-sidebar-header clickable" type="button"><!----><span class="vp-sidebar-title">应用编程接口</span><span class="vp-arrow end"></span></button><!----></section></li><li><section class="vp-sidebar-group"><button class="vp-sidebar-header clickable" type="button"><!----><span class="vp-sidebar-title">元数据操作</span><span class="vp-arrow end"></span></button><!----></section></li><li><section class="vp-sidebar-group"><button class="vp-sidebar-header clickable" type="button"><!----><span class="vp-sidebar-title">数据写入和删除</span><span class="vp-arrow end"></span></button><!----></section></li><li><section class="vp-sidebar-group"><button class="vp-sidebar-header clickable" type="button"><!----><span class="vp-sidebar-title">数据查询</span><span class="vp-arrow end"></span></button><!----></section></li><li><section class="vp-sidebar-group"><button class="vp-sidebar-header clickable active" type="button"><!----><span class="vp-sidebar-title">数据处理</span><span class="vp-arrow down"></span></button><ul class="vp-sidebar-links"><li><a class="route-link nav-link active vp-sidebar-link vp-sidebar-page active" href="/zh/UserGuide/V0.13.x/Process-Data/UDF-User-Defined-Function.html" aria-label="用户定义函数(UDF)"><!---->用户定义函数(UDF)<!----></a></li><li><a class="route-link nav-link vp-sidebar-link vp-sidebar-page" href="/zh/UserGuide/V0.13.x/Process-Data/Select-Into.html" aria-label="查询写回(SELECT INTO)"><!---->查询写回(SELECT INTO)<!----></a></li><li><a class="route-link nav-link vp-sidebar-link vp-sidebar-page" href="/zh/UserGuide/V0.13.x/Process-Data/Continuous-Query.html" aria-label="连续查询(CQ)"><!---->连续查询(CQ)<!----></a></li><li><a class="route-link nav-link vp-sidebar-link vp-sidebar-page" href="/zh/UserGuide/V0.13.x/Process-Data/Triggers.html" aria-label="触发器"><!---->触发器<!----></a></li><li><a class="route-link nav-link vp-sidebar-link vp-sidebar-page" href="/zh/UserGuide/V0.13.x/Process-Data/Alerting.html" aria-label="告警机制"><!---->告警机制<!----></a></li></ul></section></li><li><section class="vp-sidebar-group"><button class="vp-sidebar-header clickable" type="button"><!----><span class="vp-sidebar-title">权限管理</span><span class="vp-arrow end"></span></button><!----></section></li><li><section class="vp-sidebar-group"><button class="vp-sidebar-header clickable" type="button"><!----><span class="vp-sidebar-title">运维工具</span><span class="vp-arrow end"></span></button><!----></section></li><li><section class="vp-sidebar-group"><button class="vp-sidebar-header clickable" type="button"><!----><span class="vp-sidebar-title">系统集成</span><span class="vp-arrow end"></span></button><!----></section></li><li><section class="vp-sidebar-group"><button class="vp-sidebar-header clickable" type="button"><!----><span class="vp-sidebar-title">UDF 资料库</span><span class="vp-arrow end"></span></button><!----></section></li><li><section class="vp-sidebar-group"><button class="vp-sidebar-header clickable" type="button"><!----><span class="vp-sidebar-title">参考</span><span class="vp-arrow end"></span></button><!----></section></li></ul><!--[--><!----><!--]--></aside><!--[--><main id="main-content" class="vp-page"><!--[--><!--[--><!----><!--]--><!----><nav class="vp-breadcrumb disable"></nav><div class="vp-page-title"><h1><!---->数据处理</h1><div class="page-info"><!----><!----><span class="page-date-info" aria-label="写作日期"><svg xmlns="http://www.w3.org/2000/svg" class="icon calendar-icon" viewBox="0 0 1024 1024" fill="currentColor" aria-label="calendar icon"><path d="M716.4 110.137c0-18.753-14.72-33.473-33.472-33.473-18.753 0-33.473 14.72-33.473 33.473v33.473h66.993v-33.473zm-334.87 0c0-18.753-14.72-33.473-33.473-33.473s-33.52 14.72-33.52 33.473v33.473h66.993v-33.473zm468.81 33.52H716.4v100.465c0 18.753-14.72 33.473-33.472 33.473a33.145 33.145 0 01-33.473-33.473V143.657H381.53v100.465c0 18.753-14.72 33.473-33.473 33.473a33.145 33.145 0 01-33.473-33.473V143.657H180.6A134.314 134.314 0 0046.66 277.595v535.756A134.314 134.314 0 00180.6 947.289h669.74a134.36 134.36 0 00133.94-133.938V277.595a134.314 134.314 0 00-133.94-133.938zm33.473 267.877H147.126a33.145 33.145 0 01-33.473-33.473c0-18.752 14.72-33.473 33.473-33.473h736.687c18.752 0 33.472 14.72 33.472 33.473a33.145 33.145 0 01-33.472 33.473z"></path></svg><span><!----></span><meta property="datePublished" content="2023-07-10T03:11:17.000Z"></span><span class="page-pageview-info" aria-label="访问量"><svg xmlns="http://www.w3.org/2000/svg" class="icon eye-icon" viewBox="0 0 1024 1024" fill="currentColor" aria-label="eye icon"><path d="M992 512.096c0-5.76-.992-10.592-1.28-11.136-.192-2.88-1.152-8.064-2.08-10.816-.256-.672-.544-1.376-.832-2.08-.48-1.568-1.024-3.104-1.6-4.32C897.664 290.112 707.104 160 512 160c-195.072 0-385.632 130.016-473.76 322.592-1.056 2.112-1.792 4.096-2.272 5.856a55.512 55.512 0 00-.64 1.6c-1.76 5.088-1.792 8.64-1.632 7.744-.832 3.744-1.568 11.168-1.568 11.168-.224 2.272-.224 4.032.032 6.304 0 0 .736 6.464 1.088 7.808.128 1.824.576 4.512 1.12 6.976h-.032c.448 2.08 1.12 4.096 1.984 6.08.48 1.536.992 2.976 1.472 4.032C126.432 733.856 316.992 864 512 864c195.136 0 385.696-130.048 473.216-321.696 1.376-2.496 2.24-4.832 2.848-6.912.256-.608.48-1.184.672-1.728 1.536-4.48 1.856-8.32 1.728-8.32l-.032.032c.608-3.104 1.568-7.744 1.568-13.28zM512 672c-88.224 0-160-71.776-160-160s71.776-160 160-160 160 71.776 160 160-71.776 160-160 160z"></path></svg><span id="ArtalkPV" class="vp-pageview waline-pageview-count" data-path="/zh/UserGuide/V0.13.x/Process-Data/UDF-User-Defined-Function.html" data-page-key="/zh/UserGuide/V0.13.x/Process-Data/UDF-User-Defined-Function.html">...</span></span><span class="page-reading-time-info" aria-label="阅读时间"><svg xmlns="http://www.w3.org/2000/svg" class="icon timer-icon" viewBox="0 0 1024 1024" fill="currentColor" aria-label="timer icon"><path d="M799.387 122.15c4.402-2.978 7.38-7.897 7.38-13.463v-1.165c0-8.933-7.38-16.312-16.312-16.312H256.33c-8.933 0-16.311 7.38-16.311 16.312v1.165c0 5.825 2.977 10.874 7.637 13.592 4.143 194.44 97.22 354.963 220.201 392.763-122.204 37.542-214.893 196.511-220.2 389.397-4.661 5.049-7.638 11.651-7.638 19.03v5.825h566.49v-5.825c0-7.379-2.849-13.981-7.509-18.9-5.049-193.016-97.867-351.985-220.2-389.527 123.24-37.67 216.446-198.453 220.588-392.892zM531.16 450.445v352.632c117.674 1.553 211.787 40.778 211.787 88.676H304.097c0-48.286 95.149-87.382 213.728-88.676V450.445c-93.077-3.107-167.901-81.297-167.901-177.093 0-8.803 6.99-15.793 15.793-15.793 8.803 0 15.794 6.99 15.794 15.793 0 80.261 63.69 145.635 142.01 145.635s142.011-65.374 142.011-145.635c0-8.803 6.99-15.793 15.794-15.793s15.793 6.99 15.793 15.793c0 95.019-73.789 172.82-165.96 177.093z"></path></svg><span>大约 18 分钟</span><meta property="timeRequired" content="PT18M"></span><!----><!----></div><hr></div><div class="vp-toc-placeholder"><aside id="toc"><!--[--><!----><!--]--><div class="vp-toc-header">此页内容<button type="button" class="print-button" title="打印"><svg xmlns="http://www.w3.org/2000/svg" class="icon print-icon" viewBox="0 0 1024 1024" fill="currentColor" aria-label="print icon"><path d="M819.2 364.8h-44.8V128c0-17.067-14.933-32-32-32H281.6c-17.067 0-32 14.933-32 32v236.8h-44.8C145.067 364.8 96 413.867 96 473.6v192c0 59.733 49.067 108.8 108.8 108.8h44.8V896c0 17.067 14.933 32 32 32h460.8c17.067 0 32-14.933 32-32V774.4h44.8c59.733 0 108.8-49.067 108.8-108.8v-192c0-59.733-49.067-108.8-108.8-108.8zM313.6 160h396.8v204.8H313.6V160zm396.8 704H313.6V620.8h396.8V864zM864 665.6c0 25.6-19.2 44.8-44.8 44.8h-44.8V588.8c0-17.067-14.933-32-32-32H281.6c-17.067 0-32 14.933-32 32v121.6h-44.8c-25.6 0-44.8-19.2-44.8-44.8v-192c0-25.6 19.2-44.8 44.8-44.8h614.4c25.6 0 44.8 19.2 44.8 44.8v192z"></path></svg></button><div class="arrow end"></div></div><div class="vp-toc-wrapper"><ul class="vp-toc-list"><!--[--><li class="vp-toc-item"><a class="route-link vp-toc-link level2" href="#用户定义函数-udf">用户定义函数 (UDF)</a></li><li><ul class="vp-toc-list"><!--[--><li class="vp-toc-item"><a class="route-link vp-toc-link level3" href="#udf-类型">UDF 类型</a></li><!----><!--]--><!--[--><li class="vp-toc-item"><a class="route-link vp-toc-link level3" href="#udf-依赖">UDF 依赖</a></li><!----><!--]--><!--[--><li class="vp-toc-item"><a class="route-link vp-toc-link level3" href="#udtf-user-defined-timeseries-generating-function">UDTF(User Defined Timeseries Generating Function)</a></li><!----><!--]--><!--[--><li class="vp-toc-item"><a class="route-link vp-toc-link level3" href="#完整-maven-项目示例">完整 Maven 项目示例</a></li><!----><!--]--><!--[--><li class="vp-toc-item"><a class="route-link vp-toc-link level3" href="#贡献-udf">贡献 UDF</a></li><!----><!--]--><!--[--><li class="vp-toc-item"><a class="route-link vp-toc-link level3" href="#已知的-udf-库实现">已知的 UDF 库实现</a></li><!----><!--]--><!--[--><li class="vp-toc-item"><a class="route-link vp-toc-link level3" href="#q-a">Q&amp;A</a></li><!----><!--]--></ul></li><!--]--></ul><div class="vp-toc-marker" style="top:-1.7rem;"></div></div><!--[--><!----><!--]--></aside></div><!--[--><!----><!--]--><div class="theme-hope-content"><h1 id="数据处理" tabindex="-1"><a class="header-anchor" href="#数据处理"><span>数据处理</span></a></h1><h2 id="用户定义函数-udf" tabindex="-1"><a class="header-anchor" href="#用户定义函数-udf"><span>用户定义函数 (UDF)</span></a></h2><p>UDF(User Defined Function)即用户自定义函数。IoTDB 提供多种内建函数来满足您的计算需求,同时您还可以通过创建自定义函数来满足更多的计算需求。</p><p>根据此文档,您将会很快学会 UDF 的编写、注册、使用等操作。</p><h3 id="udf-类型" tabindex="-1"><a class="header-anchor" href="#udf-类型"><span>UDF 类型</span></a></h3><p>IoTDB 支持两种类型的 UDF 函数,如下表所示。</p><table><thead><tr><th>UDF 分类</th><th>描述</th></tr></thead><tbody><tr><td>UDTF(User Defined Timeseries Generating Function)</td><td>自定义时间序列生成函数。该类函数允许接收多条时间序列,最终会输出一条时间序列,生成的时间序列可以有任意多数量的数据点。</td></tr><tr><td>UDAF(User Defined Aggregation Function)</td><td>正在开发,敬请期待。</td></tr></tbody></table><h3 id="udf-依赖" tabindex="-1"><a class="header-anchor" href="#udf-依赖"><span>UDF 依赖</span></a></h3><p>如果您使用 <a href="http://search.maven.org/" target="_blank" rel="noopener noreferrer">Maven<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span></a>,可以从 <a href="http://search.maven.org/" target="_blank" rel="noopener noreferrer">Maven 库<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span></a> 中搜索下面示例中的依赖。请注意选择和目标 IoTDB 服务器版本相同的依赖版本。</p><div class="language-xml line-numbers-mode" data-ext="xml" data-title="xml"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.apache.iotdb<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>iotdb-server<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">&gt;</span></span>0.13.0-SNAPSHOT<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>scope</span><span class="token punctuation">&gt;</span></span>provided<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>scope</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="udtf-user-defined-timeseries-generating-function" tabindex="-1"><a class="header-anchor" href="#udtf-user-defined-timeseries-generating-function"><span>UDTF(User Defined Timeseries Generating Function)</span></a></h3><p>编写一个 UDTF 需要继承<code>org.apache.iotdb.db.query.udf.api.UDTF</code>类,并至少实现<code>beforeStart</code>方法和一种<code>transform</code>方法。</p><p>下表是所有可供用户实现的接口说明。</p><table><thead><tr><th style="text-align:left;">接口定义</th><th style="text-align:left;">描述</th><th>是否必须</th></tr></thead><tbody><tr><td style="text-align:left;"><code>void validate(UDFParameterValidator validator) throws Exception</code></td><td style="text-align:left;">在初始化方法<code>beforeStart</code>调用前执行,用于检测<code>UDFParameters</code>中用户输入的参数是否合法。</td><td></td></tr><tr><td style="text-align:left;"><code>void beforeStart(UDFParameters parameters, UDTFConfigurations configurations) throws Exception</code></td><td style="text-align:left;">初始化方法,在 UDTF 处理输入数据前,调用用户自定义的初始化行为。用户每执行一次 UDTF 查询,框架就会构造一个新的 UDF 类实例,该方法在每个 UDF 类实例被初始化时调用一次。在每一个 UDF 类实例的生命周期内,该方法只会被调用一次。</td><td></td></tr><tr><td style="text-align:left;"><code>void transform(Row row, PointCollector collector) throws Exception</code></td><td style="text-align:left;">这个方法由框架调用。当您在<code>beforeStart</code>中选择以<code>RowByRowAccessStrategy</code>的策略消费原始数据时,这个数据处理方法就会被调用。输入参数以<code>Row</code>的形式传入,输出结果通过<code>PointCollector</code>输出。您需要在该方法内自行调用<code>collector</code>提供的数据收集方法,以决定最终的输出数据。</td><td>与下面的方法二选一</td></tr><tr><td style="text-align:left;"><code>void transform(RowWindow rowWindow, PointCollector collector) throws Exception</code></td><td style="text-align:left;">这个方法由框架调用。当您在<code>beforeStart</code>中选择以<code>SlidingSizeWindowAccessStrategy</code>或者<code>SlidingTimeWindowAccessStrategy</code>的策略消费原始数据时,这个数据处理方法就会被调用。输入参数以<code>RowWindow</code>的形式传入,输出结果通过<code>PointCollector</code>输出。您需要在该方法内自行调用<code>collector</code>提供的数据收集方法,以决定最终的输出数据。</td><td>与上面的方法二选一</td></tr><tr><td style="text-align:left;"><code>void terminate(PointCollector collector) throws Exception</code></td><td style="text-align:left;">这个方法由框架调用。该方法会在所有的<code>transform</code>调用执行完成后,在<code>beforeDestory</code>方法执行前被调用。在一个 UDF 查询过程中,该方法会且只会调用一次。您需要在该方法内自行调用<code>collector</code>提供的数据收集方法,以决定最终的输出数据。</td><td></td></tr><tr><td style="text-align:left;"><code>void beforeDestroy() </code></td><td style="text-align:left;">UDTF 的结束方法。此方法由框架调用,并且只会被调用一次,即在处理完最后一条记录之后被调用。</td><td></td></tr></tbody></table><p>在一个完整的 UDTF 实例生命周期中,各个方法的调用顺序如下:</p><ol><li><code>void validate(UDFParameterValidator validator) throws Exception</code></li><li><code>void beforeStart(UDFParameters parameters, UDTFConfigurations configurations) throws Exception</code></li><li><code>void transform(Row row, PointCollector collector) throws Exception</code>或者<code>void transform(RowWindow rowWindow, PointCollector collector) throws Exception</code></li><li><code>void terminate(PointCollector collector) throws Exception</code></li><li><code>void beforeDestroy() </code></li></ol><p>注意,框架每执行一次 UDTF 查询,都会构造一个全新的 UDF 类实例,查询结束时,对应的 UDF 类实例即被销毁,因此不同 UDTF 查询(即使是在同一个 SQL 语句中)UDF 类实例内部的数据都是隔离的。您可以放心地在 UDTF 中维护一些状态数据,无需考虑并发对 UDF 类实例内部状态数据的影响。</p><p>下面将详细介绍各个接口的使用方法。</p><ul><li>void validate(UDFParameterValidator validator) throws Exception</li></ul><p><code>validate</code>方法能够对用户输入的参数进行验证。</p><p>您可以在该方法中限制输入序列的数量和类型,检查用户输入的属性或者进行自定义逻辑的验证。</p><p><code>UDFParameterValidator</code>的使用方法请见 Javadoc。</p><ul><li>void beforeStart(UDFParameters parameters, UDTFConfigurations configurations) throws Exception</li></ul><p><code>beforeStart</code>方法有两个作用:</p><ol><li>帮助用户解析 SQL 语句中的 UDF 参数</li><li>配置 UDF 运行时必要的信息,即指定 UDF 访问原始数据时采取的策略和输出结果序列的类型</li><li>创建资源,比如建立外部链接,打开文件等。</li></ol><h4 id="udfparameters" tabindex="-1"><a class="header-anchor" href="#udfparameters"><span>UDFParameters</span></a></h4><p><code>UDFParameters</code>的作用是解析 SQL 语句中的 UDF 参数(SQL 中 UDF 函数名称后括号中的部分)。参数包括路径(及其序列类型)参数和字符串 key-value 对形式输入的属性参数。</p><p>例子:</p><div class="language-sql line-numbers-mode" data-ext="sql" data-title="sql"><pre class="language-sql"><code><span class="token keyword">SELECT</span> UDF<span class="token punctuation">(</span>s1<span class="token punctuation">,</span> s2<span class="token punctuation">,</span> <span class="token string">&#39;key1&#39;</span><span class="token operator">=</span><span class="token string">&#39;iotdb&#39;</span><span class="token punctuation">,</span> <span class="token string">&#39;key2&#39;</span><span class="token operator">=</span><span class="token string">&#39;123.45&#39;</span><span class="token punctuation">)</span> <span class="token keyword">FROM</span> root<span class="token punctuation">.</span>sg<span class="token punctuation">.</span>d<span class="token punctuation">;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><p>用法:</p><div class="language-java line-numbers-mode" data-ext="java" data-title="java"><pre class="language-java"><code><span class="token keyword">void</span> <span class="token function">beforeStart</span><span class="token punctuation">(</span><span class="token class-name">UDFParameters</span> parameters<span class="token punctuation">,</span> <span class="token class-name">UDTFConfigurations</span> configurations<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span> <span class="token punctuation">{</span>
<span class="token comment">// parameters</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token class-name">PartialPath</span> path <span class="token operator">:</span> parameters<span class="token punctuation">.</span><span class="token function">getPaths</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token class-name">TSDataType</span> dataType <span class="token operator">=</span> parameters<span class="token punctuation">.</span><span class="token function">getDataType</span><span class="token punctuation">(</span>path<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// do something</span>
<span class="token punctuation">}</span>
<span class="token class-name">String</span> stringValue <span class="token operator">=</span> parameters<span class="token punctuation">.</span><span class="token function">getString</span><span class="token punctuation">(</span><span class="token string">&quot;key1&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// iotdb</span>
<span class="token class-name">Float</span> floatValue <span class="token operator">=</span> parameters<span class="token punctuation">.</span><span class="token function">getFloat</span><span class="token punctuation">(</span><span class="token string">&quot;key2&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 123.45</span>
<span class="token class-name">Double</span> doubleValue <span class="token operator">=</span> parameters<span class="token punctuation">.</span><span class="token function">getDouble</span><span class="token punctuation">(</span><span class="token string">&quot;key3&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// null</span>
<span class="token keyword">int</span> intValue <span class="token operator">=</span> parameters<span class="token punctuation">.</span><span class="token function">getIntOrDefault</span><span class="token punctuation">(</span><span class="token string">&quot;key4&quot;</span><span class="token punctuation">,</span> <span class="token number">678</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 678</span>
<span class="token comment">// do something</span>
<span class="token comment">// configurations</span>
<span class="token comment">// ...</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="udtfconfigurations" tabindex="-1"><a class="header-anchor" href="#udtfconfigurations"><span>UDTFConfigurations</span></a></h4><p>您必须使用 <code>UDTFConfigurations</code> 指定 UDF 访问原始数据时采取的策略和输出结果序列的类型。</p><p>用法:</p><div class="language-java line-numbers-mode" data-ext="java" data-title="java"><pre class="language-java"><code><span class="token keyword">void</span> <span class="token function">beforeStart</span><span class="token punctuation">(</span><span class="token class-name">UDFParameters</span> parameters<span class="token punctuation">,</span> <span class="token class-name">UDTFConfigurations</span> configurations<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span> <span class="token punctuation">{</span>
<span class="token comment">// parameters</span>
<span class="token comment">// ...</span>
<span class="token comment">// configurations</span>
configurations
<span class="token punctuation">.</span><span class="token function">setAccessStrategy</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">RowByRowAccessStrategy</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">setOutputDataType</span><span class="token punctuation">(</span><span class="token class-name">TSDataType</span><span class="token punctuation">.</span><span class="token constant">INT32</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>其中<code>setAccessStrategy</code>方法用于设定 UDF 访问原始数据时采取的策略,<code>setOutputDataType</code>用于设定输出结果序列的类型。</p><ul><li>setAccessStrategy</li></ul><p>注意,您在此处设定的原始数据访问策略决定了框架会调用哪一种<code>transform</code>方法 ,请实现与原始数据访问策略对应的<code>transform</code>方法。当然,您也可以根据<code>UDFParameters</code>解析出来的属性参数,动态决定设定哪一种策略,因此,实现两种<code>transform</code>方法也是被允许的。</p><p>下面是您可以设定的访问原始数据的策略:</p><table><thead><tr><th style="text-align:left;">接口定义</th><th style="text-align:left;">描述</th><th>调用的<code>transform</code>方法</th></tr></thead><tbody><tr><td style="text-align:left;"><code>RowByRowAccessStrategy</code></td><td style="text-align:left;">逐行地处理原始数据。框架会为每一行原始数据输入调用一次<code>transform</code>方法。当 UDF 只有一个输入序列时,一行输入就是该输入序列中的一个数据点。当 UDF 有多个输入序列时,一行输入序列对应的是这些输入序列按时间对齐后的结果(一行数据中,可能存在某一列为<code>null</code>值,但不会全部都是<code>null</code>)。</td><td><code>void transform(Row row, PointCollector collector) throws Exception</code></td></tr><tr><td style="text-align:left;"><code>SlidingTimeWindowAccessStrategy</code></td><td style="text-align:left;">以滑动时间窗口的方式处理原始数据。框架会为每一个原始数据输入窗口调用一次<code>transform</code>方法。一个窗口可能存在多行数据,每一行数据对应的是输入序列按时间对齐后的结果(一行数据中,可能存在某一列为<code>null</code>值,但不会全部都是<code>null</code>)。</td><td><code>void transform(RowWindow rowWindow, PointCollector collector) throws Exception</code></td></tr><tr><td style="text-align:left;"><code>SlidingSizeWindowAccessStrategy</code></td><td style="text-align:left;">以固定行数的方式处理原始数据,即每个数据处理窗口都会包含固定行数的数据(最后一个窗口除外)。框架会为每一个原始数据输入窗口调用一次<code>transform</code>方法。一个窗口可能存在多行数据,每一行数据对应的是输入序列按时间对齐后的结果(一行数据中,可能存在某一列为<code>null</code>值,但不会全部都是<code>null</code>)。</td><td><code>void transform(RowWindow rowWindow, PointCollector collector) throws Exception</code></td></tr></tbody></table><p><code>RowByRowAccessStrategy</code>的构造不需要任何参数。</p><p><code>SlidingTimeWindowAccessStrategy</code>有多种构造方法,您可以向构造方法提供 3 类参数:</p><ol><li>时间轴显示时间窗开始和结束时间</li><li>划分时间轴的时间间隔参数(必须为正数)</li><li>滑动步长(不要求大于等于时间间隔,但是必须为正数)</li></ol><p>时间轴显示时间窗开始和结束时间不是必须要提供的。当您不提供这类参数时,时间轴显示时间窗开始时间会被定义为整个查询结果集中最小的时间戳,时间轴显示时间窗结束时间会被定义为整个查询结果集中最大的时间戳。</p><p>滑动步长参数也不是必须的。当您不提供滑动步长参数时,滑动步长会被设定为划分时间轴的时间间隔。</p><p>3 类参数的关系可见下图。策略的构造方法详见 Javadoc。</p><img style="width:100%;max-width:800px;max-height:600px;margin-left:auto;margin-right:auto;display:block;" src="https://alioss.timecho.com/docs/img/github/99787878-47b51480-2b5b-11eb-8ed3-84088c5c30f7.png"><p>注意,最后的一些时间窗口的实际时间间隔可能小于规定的时间间隔参数。另外,可能存在某些时间窗口内数据行数量为 0 的情况,这种情况框架也会为该窗口调用一次<code>transform</code>方法。</p><p><code>SlidingSizeWindowAccessStrategy</code>有多种构造方法,您可以向构造方法提供 2 个参数:</p><ol><li>窗口大小,即一个数据处理窗口包含的数据行数。注意,最后一些窗口的数据行数可能少于规定的数据行数。</li><li>滑动步长,即下一窗口第一个数据行与当前窗口第一个数据行间的数据行数(不要求大于等于窗口大小,但是必须为正数)</li></ol><p>滑动步长参数不是必须的。当您不提供滑动步长参数时,滑动步长会被设定为窗口大小。</p><p>策略的构造方法详见 Javadoc。</p><ul><li>setOutputDataType</li></ul><p>注意,您在此处设定的输出结果序列的类型,决定了<code>transform</code>方法中<code>PointCollector</code>实际能够接收的数据类型。<code>setOutputDataType</code>中设定的输出类型和<code>PointCollector</code>实际能够接收的数据输出类型关系如下:</p><table><thead><tr><th style="text-align:left;"><code>setOutputDataType</code>中设定的输出类型</th><th style="text-align:left;"><code>PointCollector</code>实际能够接收的输出类型</th></tr></thead><tbody><tr><td style="text-align:left;"><code>INT32</code></td><td style="text-align:left;"><code>int</code></td></tr><tr><td style="text-align:left;"><code>INT64</code></td><td style="text-align:left;"><code>long</code></td></tr><tr><td style="text-align:left;"><code>FLOAT</code></td><td style="text-align:left;"><code>float</code></td></tr><tr><td style="text-align:left;"><code>DOUBLE</code></td><td style="text-align:left;"><code>double</code></td></tr><tr><td style="text-align:left;"><code>BOOLEAN</code></td><td style="text-align:left;"><code>boolean</code></td></tr><tr><td style="text-align:left;"><code>TEXT</code></td><td style="text-align:left;"><code>java.lang.String</code><code>org.apache.iotdb.tsfile.utils.Binary</code></td></tr></tbody></table><p>UDTF 输出序列的类型是运行时决定的。您可以根据输入序列类型动态决定输出序列类型。</p><p>下面是一个简单的例子:</p><div class="language-java line-numbers-mode" data-ext="java" data-title="java"><pre class="language-java"><code><span class="token keyword">void</span> <span class="token function">beforeStart</span><span class="token punctuation">(</span><span class="token class-name">UDFParameters</span> parameters<span class="token punctuation">,</span> <span class="token class-name">UDTFConfigurations</span> configurations<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span> <span class="token punctuation">{</span>
<span class="token comment">// do something</span>
<span class="token comment">// ...</span>
configurations
<span class="token punctuation">.</span><span class="token function">setAccessStrategy</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">RowByRowAccessStrategy</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">setOutputDataType</span><span class="token punctuation">(</span>parameters<span class="token punctuation">.</span><span class="token function">getDataType</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><ul><li>void transform(Row row, PointCollector collector) throws Exception</li></ul><p>当您在<code>beforeStart</code>方法中指定 UDF 读取原始数据的策略为 <code>RowByRowAccessStrategy</code>,您就需要实现该方法,在该方法中增加对原始数据处理的逻辑。</p><p>该方法每次处理原始数据的一行。原始数据由<code>Row</code>读入,由<code>PointCollector</code>输出。您可以选择在一次<code>transform</code>方法调用中输出任意数量的数据点。需要注意的是,输出数据点的类型必须与您在<code>beforeStart</code>方法中设置的一致,而输出数据点的时间戳必须是严格单调递增的。</p><p>下面是一个实现了<code>void transform(Row row, PointCollector collector) throws Exception</code>方法的完整 UDF 示例。它是一个加法器,接收两列时间序列输入,当这两个数据点都不为<code>null</code>时,输出这两个数据点的代数和。</p><div class="language-java line-numbers-mode" data-ext="java" data-title="java"><pre class="language-java"><code><span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>iotdb<span class="token punctuation">.</span>db<span class="token punctuation">.</span>query<span class="token punctuation">.</span>udf<span class="token punctuation">.</span>api<span class="token punctuation">.</span></span><span class="token class-name">UDTF</span></span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>iotdb<span class="token punctuation">.</span>db<span class="token punctuation">.</span>query<span class="token punctuation">.</span>udf<span class="token punctuation">.</span>api<span class="token punctuation">.</span>access<span class="token punctuation">.</span></span><span class="token class-name">Row</span></span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>iotdb<span class="token punctuation">.</span>db<span class="token punctuation">.</span>query<span class="token punctuation">.</span>udf<span class="token punctuation">.</span>api<span class="token punctuation">.</span>collector<span class="token punctuation">.</span></span><span class="token class-name">PointCollector</span></span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>iotdb<span class="token punctuation">.</span>db<span class="token punctuation">.</span>query<span class="token punctuation">.</span>udf<span class="token punctuation">.</span>api<span class="token punctuation">.</span>customizer<span class="token punctuation">.</span>config<span class="token punctuation">.</span></span><span class="token class-name">UDTFConfigurations</span></span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>iotdb<span class="token punctuation">.</span>db<span class="token punctuation">.</span>query<span class="token punctuation">.</span>udf<span class="token punctuation">.</span>api<span class="token punctuation">.</span>customizer<span class="token punctuation">.</span>parameter<span class="token punctuation">.</span></span><span class="token class-name">UDFParameters</span></span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>iotdb<span class="token punctuation">.</span>db<span class="token punctuation">.</span>query<span class="token punctuation">.</span>udf<span class="token punctuation">.</span>api<span class="token punctuation">.</span>customizer<span class="token punctuation">.</span>strategy<span class="token punctuation">.</span></span><span class="token class-name">RowByRowAccessStrategy</span></span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>iotdb<span class="token punctuation">.</span>tsfile<span class="token punctuation">.</span>file<span class="token punctuation">.</span>metadata<span class="token punctuation">.</span>enums<span class="token punctuation">.</span></span><span class="token class-name">TSDataType</span></span><span class="token punctuation">;</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Adder</span> <span class="token keyword">implements</span> <span class="token class-name">UDTF</span> <span class="token punctuation">{</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">beforeStart</span><span class="token punctuation">(</span><span class="token class-name">UDFParameters</span> parameters<span class="token punctuation">,</span> <span class="token class-name">UDTFConfigurations</span> configurations<span class="token punctuation">)</span> <span class="token punctuation">{</span>
configurations
<span class="token punctuation">.</span><span class="token function">setOutputDataType</span><span class="token punctuation">(</span><span class="token class-name">TSDataType</span><span class="token punctuation">.</span><span class="token constant">INT64</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">setAccessStrategy</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">RowByRowAccessStrategy</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">transform</span><span class="token punctuation">(</span><span class="token class-name">Row</span> row<span class="token punctuation">,</span> <span class="token class-name">PointCollector</span> collector<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span> <span class="token punctuation">{</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>row<span class="token punctuation">.</span><span class="token function">isNull</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">||</span> row<span class="token punctuation">.</span><span class="token function">isNull</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
collector<span class="token punctuation">.</span><span class="token function">putLong</span><span class="token punctuation">(</span>row<span class="token punctuation">.</span><span class="token function">getTime</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> row<span class="token punctuation">.</span><span class="token function">getLong</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> row<span class="token punctuation">.</span><span class="token function">getLong</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><ul><li>void transform(RowWindow rowWindow, PointCollector collector) throws Exception</li></ul><p>当您在<code>beforeStart</code>方法中指定 UDF 读取原始数据的策略为 <code>SlidingTimeWindowAccessStrategy</code>或者<code>SlidingSizeWindowAccessStrategy</code>时,您就需要实现该方法,在该方法中增加对原始数据处理的逻辑。</p><p>该方法每次处理固定行数或者固定时间间隔内的一批数据,我们称包含这一批数据的容器为窗口。原始数据由<code>RowWindow</code>读入,由<code>PointCollector</code>输出。<code>RowWindow</code>能够帮助您访问某一批次的<code>Row</code>,它提供了对这一批次的<code>Row</code>进行随机访问和迭代访问的接口。您可以选择在一次<code>transform</code>方法调用中输出任意数量的数据点,需要注意的是,输出数据点的类型必须与您在<code>beforeStart</code>方法中设置的一致,而输出数据点的时间戳必须是严格单调递增的。</p><p>下面是一个实现了<code>void transform(RowWindow rowWindow, PointCollector collector) throws Exception</code>方法的完整 UDF 示例。它是一个计数器,接收任意列数的时间序列输入,作用是统计并输出指定时间范围内每一个时间窗口中的数据行数。</p><div class="language-java line-numbers-mode" data-ext="java" data-title="java"><pre class="language-java"><code><span class="token keyword">import</span> <span class="token import"><span class="token namespace">java<span class="token punctuation">.</span>io<span class="token punctuation">.</span></span><span class="token class-name">IOException</span></span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>iotdb<span class="token punctuation">.</span>db<span class="token punctuation">.</span>query<span class="token punctuation">.</span>udf<span class="token punctuation">.</span>api<span class="token punctuation">.</span></span><span class="token class-name">UDTF</span></span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>iotdb<span class="token punctuation">.</span>db<span class="token punctuation">.</span>query<span class="token punctuation">.</span>udf<span class="token punctuation">.</span>api<span class="token punctuation">.</span>access<span class="token punctuation">.</span></span><span class="token class-name">RowWindow</span></span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>iotdb<span class="token punctuation">.</span>db<span class="token punctuation">.</span>query<span class="token punctuation">.</span>udf<span class="token punctuation">.</span>api<span class="token punctuation">.</span>collector<span class="token punctuation">.</span></span><span class="token class-name">PointCollector</span></span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>iotdb<span class="token punctuation">.</span>db<span class="token punctuation">.</span>query<span class="token punctuation">.</span>udf<span class="token punctuation">.</span>api<span class="token punctuation">.</span>customizer<span class="token punctuation">.</span>config<span class="token punctuation">.</span></span><span class="token class-name">UDTFConfigurations</span></span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>iotdb<span class="token punctuation">.</span>db<span class="token punctuation">.</span>query<span class="token punctuation">.</span>udf<span class="token punctuation">.</span>api<span class="token punctuation">.</span>customizer<span class="token punctuation">.</span>parameter<span class="token punctuation">.</span></span><span class="token class-name">UDFParameters</span></span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>iotdb<span class="token punctuation">.</span>db<span class="token punctuation">.</span>query<span class="token punctuation">.</span>udf<span class="token punctuation">.</span>api<span class="token punctuation">.</span>customizer<span class="token punctuation">.</span>strategy<span class="token punctuation">.</span></span><span class="token class-name">SlidingTimeWindowAccessStrategy</span></span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>iotdb<span class="token punctuation">.</span>tsfile<span class="token punctuation">.</span>file<span class="token punctuation">.</span>metadata<span class="token punctuation">.</span>enums<span class="token punctuation">.</span></span><span class="token class-name">TSDataType</span></span><span class="token punctuation">;</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Counter</span> <span class="token keyword">implements</span> <span class="token class-name">UDTF</span> <span class="token punctuation">{</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">beforeStart</span><span class="token punctuation">(</span><span class="token class-name">UDFParameters</span> parameters<span class="token punctuation">,</span> <span class="token class-name">UDTFConfigurations</span> configurations<span class="token punctuation">)</span> <span class="token punctuation">{</span>
configurations
<span class="token punctuation">.</span><span class="token function">setOutputDataType</span><span class="token punctuation">(</span><span class="token class-name">TSDataType</span><span class="token punctuation">.</span><span class="token constant">INT32</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">setAccessStrategy</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">SlidingTimeWindowAccessStrategy</span><span class="token punctuation">(</span>
parameters<span class="token punctuation">.</span><span class="token function">getLong</span><span class="token punctuation">(</span><span class="token string">&quot;time_interval&quot;</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
parameters<span class="token punctuation">.</span><span class="token function">getLong</span><span class="token punctuation">(</span><span class="token string">&quot;sliding_step&quot;</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
parameters<span class="token punctuation">.</span><span class="token function">getLong</span><span class="token punctuation">(</span><span class="token string">&quot;display_window_begin&quot;</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
parameters<span class="token punctuation">.</span><span class="token function">getLong</span><span class="token punctuation">(</span><span class="token string">&quot;display_window_end&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">transform</span><span class="token punctuation">(</span><span class="token class-name">RowWindow</span> rowWindow<span class="token punctuation">,</span> <span class="token class-name">PointCollector</span> collector<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span> <span class="token punctuation">{</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>rowWindow<span class="token punctuation">.</span><span class="token function">windowSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
collector<span class="token punctuation">.</span><span class="token function">putInt</span><span class="token punctuation">(</span>rowWindow<span class="token punctuation">.</span><span class="token function">getRow</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getTime</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> rowWindow<span class="token punctuation">.</span><span class="token function">windowSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><ul><li>void terminate(PointCollector collector) throws Exception</li></ul><p>在一些场景下,UDF 需要遍历完所有的原始数据后才能得到最后的输出结果。<code>terminate</code>接口为这类 UDF 提供了支持。</p><p>该方法会在所有的<code>transform</code>调用执行完成后,在<code>beforeDestory</code>方法执行前被调用。您可以选择使用<code>transform</code>方法进行单纯的数据处理,最后使用<code>terminate</code>将处理结果输出。</p><p>结果需要由<code>PointCollector</code>输出。您可以选择在一次<code>terminate</code>方法调用中输出任意数量的数据点。需要注意的是,输出数据点的类型必须与您在<code>beforeStart</code>方法中设置的一致,而输出数据点的时间戳必须是严格单调递增的。</p><p>下面是一个实现了<code>void terminate(PointCollector collector) throws Exception</code>方法的完整 UDF 示例。它接收一个<code>INT32</code>类型的时间序列输入,作用是输出该序列的最大值点。</p><div class="language-java line-numbers-mode" data-ext="java" data-title="java"><pre class="language-java"><code><span class="token keyword">import</span> <span class="token import"><span class="token namespace">java<span class="token punctuation">.</span>io<span class="token punctuation">.</span></span><span class="token class-name">IOException</span></span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>iotdb<span class="token punctuation">.</span>db<span class="token punctuation">.</span>query<span class="token punctuation">.</span>udf<span class="token punctuation">.</span>api<span class="token punctuation">.</span></span><span class="token class-name">UDTF</span></span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>iotdb<span class="token punctuation">.</span>db<span class="token punctuation">.</span>query<span class="token punctuation">.</span>udf<span class="token punctuation">.</span>api<span class="token punctuation">.</span>access<span class="token punctuation">.</span></span><span class="token class-name">Row</span></span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>iotdb<span class="token punctuation">.</span>db<span class="token punctuation">.</span>query<span class="token punctuation">.</span>udf<span class="token punctuation">.</span>api<span class="token punctuation">.</span>collector<span class="token punctuation">.</span></span><span class="token class-name">PointCollector</span></span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>iotdb<span class="token punctuation">.</span>db<span class="token punctuation">.</span>query<span class="token punctuation">.</span>udf<span class="token punctuation">.</span>api<span class="token punctuation">.</span>customizer<span class="token punctuation">.</span>config<span class="token punctuation">.</span></span><span class="token class-name">UDTFConfigurations</span></span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>iotdb<span class="token punctuation">.</span>db<span class="token punctuation">.</span>query<span class="token punctuation">.</span>udf<span class="token punctuation">.</span>api<span class="token punctuation">.</span>customizer<span class="token punctuation">.</span>parameter<span class="token punctuation">.</span></span><span class="token class-name">UDFParameters</span></span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>iotdb<span class="token punctuation">.</span>db<span class="token punctuation">.</span>query<span class="token punctuation">.</span>udf<span class="token punctuation">.</span>api<span class="token punctuation">.</span>customizer<span class="token punctuation">.</span>strategy<span class="token punctuation">.</span></span><span class="token class-name">RowByRowAccessStrategy</span></span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>iotdb<span class="token punctuation">.</span>tsfile<span class="token punctuation">.</span>file<span class="token punctuation">.</span>metadata<span class="token punctuation">.</span>enums<span class="token punctuation">.</span></span><span class="token class-name">TSDataType</span></span><span class="token punctuation">;</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Max</span> <span class="token keyword">implements</span> <span class="token class-name">UDTF</span> <span class="token punctuation">{</span>
<span class="token keyword">private</span> <span class="token class-name">Long</span> time<span class="token punctuation">;</span>
<span class="token keyword">private</span> <span class="token keyword">int</span> value<span class="token punctuation">;</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">beforeStart</span><span class="token punctuation">(</span><span class="token class-name">UDFParameters</span> parameters<span class="token punctuation">,</span> <span class="token class-name">UDTFConfigurations</span> configurations<span class="token punctuation">)</span> <span class="token punctuation">{</span>
configurations
<span class="token punctuation">.</span><span class="token function">setOutputDataType</span><span class="token punctuation">(</span><span class="token class-name">TSDataType</span><span class="token punctuation">.</span><span class="token constant">INT32</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">setAccessStrategy</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">RowByRowAccessStrategy</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">transform</span><span class="token punctuation">(</span><span class="token class-name">Row</span> row<span class="token punctuation">,</span> <span class="token class-name">PointCollector</span> collector<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">int</span> candidateValue <span class="token operator">=</span> row<span class="token punctuation">.</span><span class="token function">getInt</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>time <span class="token operator">==</span> <span class="token keyword">null</span> <span class="token operator">||</span> value <span class="token operator">&lt;</span> candidateValue<span class="token punctuation">)</span> <span class="token punctuation">{</span>
time <span class="token operator">=</span> row<span class="token punctuation">.</span><span class="token function">getTime</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
value <span class="token operator">=</span> candidateValue<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">terminate</span><span class="token punctuation">(</span><span class="token class-name">PointCollector</span> collector<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">IOException</span> <span class="token punctuation">{</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>time <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
collector<span class="token punctuation">.</span><span class="token function">putInt</span><span class="token punctuation">(</span>time<span class="token punctuation">,</span> value<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><ul><li>void beforeDestroy()</li></ul><p>UDTF 的结束方法,您可以在此方法中进行一些资源释放等的操作。</p><p>此方法由框架调用。对于一个 UDF 类实例而言,生命周期中会且只会被调用一次,即在处理完最后一条记录之后被调用。</p><h3 id="完整-maven-项目示例" tabindex="-1"><a class="header-anchor" href="#完整-maven-项目示例"><span>完整 Maven 项目示例</span></a></h3><p>如果您使用 <a href="http://search.maven.org/" target="_blank" rel="noopener noreferrer">Maven<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span></a>,可以参考我们编写的示例项目** udf-example**。您可以在 <a href="https://github.com/apache/iotdb/tree/master/example/udf" target="_blank" rel="noopener noreferrer">这里<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span></a> 找到它。</p><h4 id="udf-注册" tabindex="-1"><a class="header-anchor" href="#udf-注册"><span>UDF 注册</span></a></h4><p>注册一个 UDF 可以按如下流程进行:</p><ol><li><p>实现一个完整的 UDF 类,假定这个类的全类名为<code>org.apache.iotdb.udf.UDTFExample</code></p></li><li><p>将项目打成 JAR 包,如果您使用 Maven 管理项目,可以参考上述 Maven 项目示例的写法</p></li><li><p>将 JAR 包放置到目录 <code>iotdb-server-0.13.0-SNAPSHOT-all-bin/ext/udf</code> (也可以是<code>iotdb-server-0.13.0-SNAPSHOT-all-bin/ext/udf</code>的子目录)下。<br><strong>注意,在部署集群的时候,需要保证每一个节点的 UDF JAR 包路径下都存在相应的 JAR 包。</strong></p><blockquote><p>您可以通过修改配置文件中的<code>udf_root_dir</code>来指定 UDF 加载 Jar 的根路径。</p></blockquote></li><li><p>使用 SQL 语句注册该 UDF,假定赋予该 UDF 的名字为<code>example</code></p></li></ol><p>注册 UDF 的 SQL 语法如下:</p><div class="language-sql line-numbers-mode" data-ext="sql" data-title="sql"><pre class="language-sql"><code><span class="token keyword">CREATE</span> <span class="token keyword">FUNCTION</span> <span class="token operator">&lt;</span>UDF<span class="token operator">-</span>NAME<span class="token operator">&gt;</span> <span class="token keyword">AS</span> <span class="token operator">&lt;</span>UDF<span class="token operator">-</span>CLASS<span class="token operator">-</span><span class="token keyword">FULL</span><span class="token operator">-</span>PATHNAME<span class="token operator">&gt;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><p>例子中注册 UDF 的 SQL 语句如下:</p><div class="language-sql line-numbers-mode" data-ext="sql" data-title="sql"><pre class="language-sql"><code><span class="token keyword">CREATE</span> <span class="token keyword">FUNCTION</span> example <span class="token keyword">AS</span> <span class="token string">&#39;org.apache.iotdb.udf.UDTFExample&#39;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><p>由于 IoTDB 的 UDF 是通过反射技术动态装载的,因此您在装载过程中无需启停服务器。</p><p>注意:UDF 函数名称是大小写不敏感的。</p><p>注意:请不要给 UDF 函数注册一个内置函数的名字。使用内置函数的名字给 UDF 注册会失败。</p><p>注意:不同的 JAR 包中最好不要有全类名相同但实现功能逻辑不一样的类。例如 UDF(UDAF/UDTF):<code>udf1</code><code>udf2</code>分别对应资源<code>udf1.jar</code><code>udf2.jar</code>。如果两个 JAR 包里都包含一个<code>org.apache.iotdb.udf.UDTFExample</code>类,当同一个 SQL 中同时使用到这两个 UDF 时,系统会随机加载其中一个类,导致 UDF 执行行为不一致。</p><h4 id="udf-卸载" tabindex="-1"><a class="header-anchor" href="#udf-卸载"><span>UDF 卸载</span></a></h4><p>卸载 UDF 的 SQL 语法如下:</p><div class="language-sql line-numbers-mode" data-ext="sql" data-title="sql"><pre class="language-sql"><code><span class="token keyword">DROP</span> <span class="token keyword">FUNCTION</span> <span class="token operator">&lt;</span>UDF<span class="token operator">-</span>NAME<span class="token operator">&gt;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><p>可以通过如下 SQL 语句卸载上面例子中的 UDF:</p><div class="language-sql line-numbers-mode" data-ext="sql" data-title="sql"><pre class="language-sql"><code><span class="token keyword">DROP</span> <span class="token keyword">FUNCTION</span> example
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><h4 id="udf-查询" tabindex="-1"><a class="header-anchor" href="#udf-查询"><span>UDF 查询</span></a></h4><p>UDF 的使用方法与普通内建函数的类似。</p><h5 id="支持的基础-sql-语法" tabindex="-1"><a class="header-anchor" href="#支持的基础-sql-语法"><span>支持的基础 SQL 语法</span></a></h5><ul><li><code>SLIMIT</code> / <code>SOFFSET</code></li><li><code>LIMIT</code> / <code>OFFSET</code></li><li><code>NON ALIGN</code></li><li>支持值过滤</li><li>支持时间过滤</li></ul><h5 id="对齐时间序列查询" tabindex="-1"><a class="header-anchor" href="#对齐时间序列查询"><span>对齐时间序列查询</span></a></h5><p>UDF 查询目前不支持对对齐时间序列(Aligned Timeseries)进行查询,当您在<code>SELECT</code>子句中选择的序列中包含对齐时间序列时,会提示错误。</p><h5 id="带-查询" tabindex="-1"><a class="header-anchor" href="#带-查询"><span>带 * 查询</span></a></h5><p>假定现在有时间序列 <code>root.sg.d1.s1</code><code>root.sg.d1.s2</code></p><ul><li><strong>执行<code>SELECT example(*) from root.sg.d1</code></strong></li></ul><p>那么结果集中将包括<code>example(root.sg.d1.s1)</code><code>example(root.sg.d1.s2)</code>的结果。</p><ul><li><strong>执行<code>SELECT example(s1, *) from root.sg.d1</code></strong></li></ul><p>那么结果集中将包括<code>example(root.sg.d1.s1, root.sg.d1.s1)</code><code>example(root.sg.d1.s1, root.sg.d1.s2)</code>的结果。</p><ul><li><strong>执行<code>SELECT example(*, *) from root.sg.d1</code></strong></li></ul><p>那么结果集中将包括<code>example(root.sg.d1.s1, root.sg.d1.s1)</code><code>example(root.sg.d1.s2, root.sg.d1.s1)</code><code>example(root.sg.d1.s1, root.sg.d1.s2)</code><code>example(root.sg.d1.s2, root.sg.d1.s2)</code>的结果。</p><h5 id="带自定义输入参数的查询" tabindex="-1"><a class="header-anchor" href="#带自定义输入参数的查询"><span>带自定义输入参数的查询</span></a></h5><p>您可以在进行 UDF 查询的时候,向 UDF 传入任意数量的键值对参数。键值对中的键和值都需要被单引号或者双引号引起来。注意,键值对参数只能在所有时间序列后传入。下面是一组例子:</p><div class="language-sql line-numbers-mode" data-ext="sql" data-title="sql"><pre class="language-sql"><code><span class="token keyword">SELECT</span> example<span class="token punctuation">(</span>s1<span class="token punctuation">,</span> <span class="token string">&#39;key1&#39;</span><span class="token operator">=</span><span class="token string">&#39;value1&#39;</span><span class="token punctuation">,</span> <span class="token string">&#39;key2&#39;</span><span class="token operator">=</span><span class="token string">&#39;value2&#39;</span><span class="token punctuation">)</span><span class="token punctuation">,</span> example<span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">,</span> <span class="token string">&#39;key3&#39;</span><span class="token operator">=</span><span class="token string">&#39;value3&#39;</span><span class="token punctuation">)</span> <span class="token keyword">FROM</span> root<span class="token punctuation">.</span>sg<span class="token punctuation">.</span>d1<span class="token punctuation">;</span>
<span class="token keyword">SELECT</span> example<span class="token punctuation">(</span>s1<span class="token punctuation">,</span> s2<span class="token punctuation">,</span> <span class="token string">&#39;key1&#39;</span><span class="token operator">=</span><span class="token string">&#39;value1&#39;</span><span class="token punctuation">,</span> <span class="token string">&#39;key2&#39;</span><span class="token operator">=</span><span class="token string">&#39;value2&#39;</span><span class="token punctuation">)</span> <span class="token keyword">FROM</span> root<span class="token punctuation">.</span>sg<span class="token punctuation">.</span>d1<span class="token punctuation">;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div></div></div><h5 id="与其他查询的嵌套查询" tabindex="-1"><a class="header-anchor" href="#与其他查询的嵌套查询"><span>与其他查询的嵌套查询</span></a></h5><div class="language-sql line-numbers-mode" data-ext="sql" data-title="sql"><pre class="language-sql"><code><span class="token keyword">SELECT</span> s1<span class="token punctuation">,</span> s2<span class="token punctuation">,</span> example<span class="token punctuation">(</span>s1<span class="token punctuation">,</span> s2<span class="token punctuation">)</span> <span class="token keyword">FROM</span> root<span class="token punctuation">.</span>sg<span class="token punctuation">.</span>d1<span class="token punctuation">;</span>
<span class="token keyword">SELECT</span> <span class="token operator">*</span><span class="token punctuation">,</span> example<span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">)</span> <span class="token keyword">FROM</span> root<span class="token punctuation">.</span>sg<span class="token punctuation">.</span>d1 <span class="token keyword">DISABLE</span> ALIGN<span class="token punctuation">;</span>
<span class="token keyword">SELECT</span> s1 <span class="token operator">*</span> example<span class="token punctuation">(</span><span class="token operator">*</span> <span class="token operator">/</span> s1 <span class="token operator">+</span> s2<span class="token punctuation">)</span> <span class="token keyword">FROM</span> root<span class="token punctuation">.</span>sg<span class="token punctuation">.</span>d1<span class="token punctuation">;</span>
<span class="token keyword">SELECT</span> s1<span class="token punctuation">,</span> s2<span class="token punctuation">,</span> s1 <span class="token operator">+</span> example<span class="token punctuation">(</span>s1<span class="token punctuation">,</span> s2<span class="token punctuation">)</span><span class="token punctuation">,</span> s1 <span class="token operator">-</span> example<span class="token punctuation">(</span>s1 <span class="token operator">+</span> example<span class="token punctuation">(</span>s1<span class="token punctuation">,</span> s2<span class="token punctuation">)</span> <span class="token operator">/</span> s2<span class="token punctuation">)</span> <span class="token keyword">FROM</span> root<span class="token punctuation">.</span>sg<span class="token punctuation">.</span>d1<span class="token punctuation">;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="查看所有注册的-udf" tabindex="-1"><a class="header-anchor" href="#查看所有注册的-udf"><span>查看所有注册的 UDF</span></a></h4><div class="language-sql line-numbers-mode" data-ext="sql" data-title="sql"><pre class="language-sql"><code><span class="token keyword">SHOW</span> FUNCTIONS
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><h4 id="用户权限管理" tabindex="-1"><a class="header-anchor" href="#用户权限管理"><span>用户权限管理</span></a></h4><p>用户在使用 UDF 时会涉及到 3 种权限:</p><ul><li><code>CREATE_FUNCTION</code>:具备该权限的用户才被允许执行 UDF 注册操作</li><li><code>DROP_FUNCTION</code>:具备该权限的用户才被允许执行 UDF 卸载操作</li><li><code>READ_TIMESERIES</code>:具备该权限的用户才被允许使用 UDF 进行查询</li></ul><p>更多用户权限相关的内容,请参考 <a class="route-link" href="/zh/UserGuide/V0.13.x/Administration-Management/Administration.html">权限管理语句</a></p><h4 id="配置项" tabindex="-1"><a class="header-anchor" href="#配置项"><span>配置项</span></a></h4><p>在 SQL 语句中使用自定义函数时,可能提示内存不足。这种情况下,您可以通过更改配置文件<code>iotdb-engine.properties</code>中的<code>udf_initial_byte_array_length_for_memory_control</code><code>udf_memory_budget_in_mb</code><code>udf_reader_transformer_collector_memory_proportion</code>并重启服务来解决此问题。</p><h3 id="贡献-udf" tabindex="-1"><a class="header-anchor" href="#贡献-udf"><span>贡献 UDF</span></a></h3><p>该部分主要讲述了外部用户如何将自己编写的 UDF 贡献给 IoTDB 社区。</p><h4 id="前提条件" tabindex="-1"><a class="header-anchor" href="#前提条件"><span>前提条件</span></a></h4><ol><li><p>UDF 具有通用性。</p><p>通用性主要指的是:UDF 在某些业务场景下,可以被广泛使用。换言之,就是 UDF 具有复用价值,可被社区内其他用户直接使用。</p><p>如果您不确定自己写的 UDF 是否具有通用性,可以发邮件到 <code>dev@iotdb.apache.org</code> 或直接创建 ISSUE 发起讨论。</p></li><li><p>UDF 已经完成测试,且能够正常运行在用户的生产环境中。</p></li></ol><h4 id="贡献清单" tabindex="-1"><a class="header-anchor" href="#贡献清单"><span>贡献清单</span></a></h4><ol><li>UDF 的源代码</li><li>UDF 的测试用例</li><li>UDF 的使用说明</li></ol><h5 id="源代码" tabindex="-1"><a class="header-anchor" href="#源代码"><span>源代码</span></a></h5><ol><li><code>src/main/java/org/apache/iotdb/db/query/udf/builtin</code>或者它的子文件夹中创建 UDF 主类和相关的辅助类。</li><li><code>src/main/java/org/apache/iotdb/db/query/udf/builtin/BuiltinFunction.java</code>中注册您编写的 UDF。</li></ol><h5 id="测试用例" tabindex="-1"><a class="header-anchor" href="#测试用例"><span>测试用例</span></a></h5><p>您至少需要为您贡献的 UDF 编写集成测试。</p><p>您可以在<code>server/src/test/java/org/apache/iotdb/db/integration</code>中为您贡献的 UDF 新增一个测试类进行测试。</p><h5 id="使用说明" tabindex="-1"><a class="header-anchor" href="#使用说明"><span>使用说明</span></a></h5><p>使用说明需要包含:UDF 的名称、UDF 的作用、执行函数必须的属性参数、函数的适用的场景以及使用示例等。</p><p>使用说明需包含中英文两个版本。应分别在 <code>docs/zh/UserGuide/Operation Manual/DML Data Manipulation Language.md</code><code>docs/UserGuide/Operation Manual/DML Data Manipulation Language.md</code> 中新增使用说明。</p><h4 id="提交-pr" tabindex="-1"><a class="header-anchor" href="#提交-pr"><span>提交 PR</span></a></h4><p>当您准备好源代码、测试用例和使用说明后,就可以将 UDF 贡献到 IoTDB 社区了。在 <a href="https://github.com/apache/iotdb" target="_blank" rel="noopener noreferrer">Github<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span></a> 上面提交 Pull Request (PR) 即可。具体提交方式见:<a href="https://iotdb.apache.org/Development/HowToCommit.html" target="_blank" rel="noopener noreferrer">Pull Request Guide<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span></a></p><p>当 PR 评审通过并被合并后,您的 UDF 就已经贡献给 IoTDB 社区了!</p><h3 id="已知的-udf-库实现" tabindex="-1"><a class="header-anchor" href="#已知的-udf-库实现"><span>已知的 UDF 库实现</span></a></h3><ul><li><a href="https://iotdb.apache.org/zh/UserGuide/Master/UDF-Library/Quick-Start.html" target="_blank" rel="noopener noreferrer">IoTDB-Quality<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span></a>,一个关于数据质量的 UDF 库实现,包括数据画像、数据质量评估与修复等一系列函数。</li></ul><h3 id="q-a" tabindex="-1"><a class="header-anchor" href="#q-a"><span>Q&amp;A</span></a></h3><p>Q1: 如何修改已经注册的 UDF?</p><p>A1: 假设 UDF 的名称为<code>example</code>,全类名为<code>org.apache.iotdb.udf.UDTFExample</code>,由<code>example.jar</code>引入</p><ol><li>首先卸载已经注册的<code>example</code>函数,执行<code>DROP FUNCTION example</code></li><li>删除 <code>iotdb-server-0.13.0-SNAPSHOT-all-bin/ext/udf</code> 目录下的<code>example.jar</code></li><li>修改<code>org.apache.iotdb.udf.UDTFExample</code>中的逻辑,重新打包,JAR 包的名字可以仍然为<code>example.jar</code></li><li>将新的 JAR 包上传至 <code>iotdb-server-0.13.0-SNAPSHOT-all-bin/ext/udf</code> 目录下</li><li>装载新的 UDF,执行<code>CREATE FUNCTION example AS &quot;org.apache.iotdb.udf.UDTFExample&quot;</code></li></ol></div><!--[--><!----><!--]--><footer class="vp-page-meta"><div class="vp-meta-item edit-link"><a href="https://github.com/apache/iotdb-docs/edit/main/src/zh/UserGuide/V0.13.x/Process-Data/UDF-User-Defined-Function.md" rel="noopener noreferrer" target="_blank" aria-label="发现错误?在 GitHub 上编辑此页" class="nav-link vp-meta-label"><!--[--><svg xmlns="http://www.w3.org/2000/svg" class="icon edit-icon" viewBox="0 0 1024 1024" fill="currentColor" aria-label="edit icon"><path d="M430.818 653.65a60.46 60.46 0 0 1-50.96-93.281l71.69-114.012 7.773-10.365L816.038 80.138A60.46 60.46 0 0 1 859.225 62a60.46 60.46 0 0 1 43.186 18.138l43.186 43.186a60.46 60.46 0 0 1 0 86.373L588.879 565.55l-8.637 8.637-117.466 68.234a60.46 60.46 0 0 1-31.958 11.229z"></path><path d="M728.802 962H252.891A190.883 190.883 0 0 1 62.008 771.98V296.934a190.883 190.883 0 0 1 190.883-192.61h267.754a60.46 60.46 0 0 1 0 120.92H252.891a69.962 69.962 0 0 0-69.098 69.099V771.98a69.962 69.962 0 0 0 69.098 69.098h475.911A69.962 69.962 0 0 0 797.9 771.98V503.363a60.46 60.46 0 1 1 120.922 0V771.98A190.883 190.883 0 0 1 728.802 962z"></path></svg><!--]-->发现错误?在 GitHub 上编辑此页<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span><!----></a></div><div class="vp-meta-item git-info"><div class="update-time"><span class="vp-meta-label">上次编辑于: </span><!----></div><!----></div></footer><nav class="vp-page-nav"><!----><a class="route-link nav-link next" href="/zh/UserGuide/V0.13.x/Process-Data/Select-Into.html" aria-label="查询写回(SELECT INTO)"><div class="hint">下一页<span class="arrow end"></span></div><div class="link">查询写回(SELECT INTO)<!----></div></a></nav><!----><!--[--><!----><!--]--><!--]--></main><!--]--><footer style="padding-bottom:2rem;"><span id="doc-version" style="display:none;">rel/0.13</span><p style="text-align:center;color:#909399;font-size:12px;margin:0 30px;">Copyright © 2024 The Apache Software Foundation.<br> Apache and the Apache feather logo are trademarks of The Apache Software Foundation</p><p style="text-align:center;margin-top:10px;color:#909399;font-size:12px;margin:0 30px;"><strong>Have a question?</strong> Connect with us on QQ, WeChat, or Slack. <a href="https://github.com/apache/iotdb/issues/1995">Join the community</a> now.</p></footer></div><!--]--><!--]--><!--[--><!----><!--]--><!--]--></div>
<script type="module" src="/assets/app-DrPcRZG6.js" defer></script>
</body>
</html>