自助报表分析 3:更全面的自助报表分析
对于很多非临时性的自助查询需求要基于完整的数据库进行,这不仅要求查询范围足够广、查询灵活性更高,也要控制数据访问权限。润乾 BI 提供了 DQL 模型来完成这个目标。
在 DQL 超维分析 课程中已经详细介绍了如何基于数据库建立元数据模型,可以直接参考: DQL 超维分析
当然仅仅有元数据还不够,完整的润乾自助报表结构包括以下内容
DQL 服务器是解析元数据并与数据库交互的逻辑服务器;应用与 DQL 服务器分离,可以通过 JDBC 访问 DQL 服务,在应用中通过 DQL 模型中的词典、可视文件来进行语义转换和权限控制,采用 tag-lib 方式与页面集成进行自助报表查询。
使用时,可以先基于数据源(DQL 模型)查询数据,设置过滤条件、查看 / 下载数据;查询后的结果集还可以跳转到报表分析界面,实施进一步的多维分析。
报表分析也可以直接基于数据源进行,但由于数据量原因,直接多维分析可能会出现卡顿问题,因此建议先查询过滤数据后再分析。
发布元数据
在 [产品安装目录]\services\tpch\conf 下有已经做好的元数据文件 tpch.lmd。部署 DQL 服务也参考上面的 DQL 超维分析课程 链接,主要配置内容列一下。
DQL 服务配置 server.xml:
其中配置了 tpch 这个服务。这个服务的配置文件service.xml:
连接了具体数据库 hsql,也就是上一节课用到的数据库。
启动 DQL 服务。
然后把 DQL 服务(tpch)的 JDBC 数据源配置到应用的配置文件 {WEB 应用根目录}/WEB-INF/raqsoftConfig.xml 里,连接 URL 为 jdbc:datalogic://127.0.0.1:3366/tpch
,指明连接 DQL Server 的 tpch 服务,连接的驱动类是 com.datalogic.jdbc.LogicDriver
:
<DB name="TPCH">
<property name="url" value="jdbc:datalogic://127.0.0.1:3366/tpch"/>
<property name="driver" value="com.datalogic.jdbc.LogicDriver"/>
<property name="type" value="16"/>
<property name="user" value="root"/>
<property name="password" value="root"/>
</DB>
查询数据
基于数据库做自助报表也同样需要先准备数据集(与文件、SQL 类似)。润乾 BI 提供了专门的查询功能,用于筛选、查看、下载数据。
准备发布元数据(tpch.lmd)的页面,仍然是 tag 方式集成:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.util.*" %>
<%@ taglib uri="/WEB-INF/raqsoftAnalyse.tld" prefix="raqsoft" %>
<%
String dataSource = "TPCH";
%>
<raqsoft: detailQuery
dataSource="<%=dataSource %>"
/>
通过 dataSource 属性指定 DQL 数据源 TPCH 就能发布元数据到页面了。
元数发布后就可以随意自助查询,但是我们发现这里的表和字段都是原数据库英文的命名方式而非业务术语。
这就需要再进行语义转换,将数据库里的表、字段名替换成业务术语。
语义转换
如果每次查询时用 AS 别名会比较繁琐,DQL 提供字典 (*.dct) 可以预先定义所有表、字段的别名。元数据生成字典很简单,打开元数据文件 (tpch.lmd) 后,从菜单栏选择:系统 - 生成字典:
将表和字段名都修改成业务人员能识别的业务数术语。
包括设置显示格式:
设置维名和显示列:
把上述字典保存成 tpch.dct。
在页面中引用这个字典文件:
<%@ page import="java.util.*" %>
<%@ taglib uri="/WEB-INF/raqsoftAnalyse.tld" prefix="raqsoft" %>
<%
String dataSource = "TPCH";
%>
<raqsoft: detailQuery
dataSource="<%=dataSource %>"
/>
<script>
guideConf.dct="tpch.dct";
</script>
润乾开源免费 BI 提供了相应 JS 标签来指定字典文件。访问这个页面可以看到:
原来的英文表名和字段都显示成了业务术语,拖拽编号字段也会按名称显示。
保存自助查询
查询定义(.qyx 文件)可以保存,以便后续使用。程序员可以自由控制保存的路径和保存方式。
服务器的保存默认路径在WEB-INF\guideConf.properties中配置,使用时可以修改这个路径。
qyxFolderOnServer=WEB-INF/files/qyx/
也可以在发布页面指定保存路径
String qyxFolderOnServer = request.getParameter("qyxFolderOnServer"),
if(qyxFolderOnServer != null){
session.setAttribute(" qyxFolderOnServer ", qyxFolderOnServer);
}
如果不想把查询定义保存到文件,也可以通过 API 获取(domUtils.toString()
)查询定义的 JSON 串,自行将其保存到数据库中。
权限控制
用户正式使用时还会涉及权限,包括看到的表 / 字段、记录范围等。字典(dct)中提供了分类项功能,可以划分不同业务,做到业务级别的权限隔离。
在 tpch.dct 里,选中“分类项”标签,添加客户管理、供应商管理两个分类,可以看到“客户管理”中选出一些表和字段,排除了与客户分析无关的订单、订单明细等表:
然后在 jsp 里如下设置使用客户分析这个分类:
<script>
guideConf.dct="tpch.dct";
guideConf.className = "客户管理";
</script>
再访问界面,看到只显示“客户管理”分类下的表和字段了:
业务区分后,还要根据用户 / 角色对不同字段和数据(记录)权限控制。比如某用户不能看中东、欧洲的数据,那可以在他的 session 里针对区域表设置隐含的限定条件:
DQLTableFilter f = new DQLTableFilter("default");
f.getFilters().put("region","${T}.R_NAME NOT IN ('MIDDLE EAST','EUROPE')");
ArrayList filters = new ArrayList();
filters.add(f);
session.setAttribute("_raqsoft_filters_",filters);
页面中查询区域、国家时不设置任何条件,但也看到中东和欧洲被屏蔽了:
观察 DQL server 控制台的日志,发现查询 DQL 语句确实自动补上了 session 中的限定条件:
如果多个表都需要设置限定条件,在 JSP 中书写起来比较啰嗦,可以生成一个可视文件,集中定义各表条件。打开元数据文件 tpch.lmd,系统 - 生成可视编辑:
可视文件可以使用多个(不同用户),针对不同表和字段设置。还可以根据“条件”进行记录级别的访问控制。
之后在 JSP 里使用 tpch.vsb 就可以了:
DQLTableFilter f = new DQLTableFilter("default");
f.setVsb("tpch.vsb",request);
<img src="https://img.raqsoft.com.cn/docx/1755736056758100.png" />
不同用户的权限不同,需要设置不同的限制条件,给每个用户生成一个可视文件是不现实的,可以用宏值替换的方式定义条件:
不同登录用户共用 tpch.vsb 文件,针对 exclude 宏设置不同的的值即可:
DQLTableFilter f = new DQLTableFilter("default");
f.setVsb("tpch.vsb",request);
f.getParamValues().put("exclude","'MIDDLE EAST','EUROPE'"); //A 用户不看中东、欧洲
f.getParamValues().put("exclude","'ASIA'"); //B 用户不看亚洲
宏太多时,还可以定义一个 json 文件统一设置某用户的所有宏值:
{"MACRO_VALUES":
{
"exclude":"'ASIA'"
,"macro2":"VALUE2"
,"macro3":"VALUE3"
}
}
这个宏文件存为 {WEB 根目录}/WEB-INF/files/dql/tpch_macro.json,然后在 jsp 里使用它就可以设置上所有宏值了:
DQLTableFilter f = new DQLTableFilter("default");
f.setVsb("tpch.vsb",request);
f.setMacro("tpch_macro.json", null ,request);
多维分析
查询后的结果可以进一步做多维分析,前面几节基于固定数据集做报表分析是一样的。
点击页面上的【制作报表】按钮,跳转到分析页面:
我们在页面中增加如下 JS 就能达到相应效果:
<script>
guideConf.dct="tpch.dct";
guideConf.analysePage = "raqsoft/guide/jsp/olap.jsp"; //分析界面
</script>
事实上,可以直接使用数据源(DQL 模型)做报表分析。在发布页面嵌入分析标签就能直接对着数据源分析。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.util.*" %>
<%@ taglib uri="/WEB-INF/raqsoftAnalyse.tld" prefix="raqsoft" %>
<%
String dataSource = "TPCH";
%>
<raqsoft:analysev2
dataSource="<%=dataSource %>"
/>
<script>
guideConf.dct="tpch.dct";
</script>
保存报表分析
拖拽查询的报表定义同样可以保存(.olap 文件),以方便后续使用。
默认保存路径仍然在 WEB-INF\guideConf.properties 中配置。
olapFolderOnServer=WEB-INF/files/olap/
也可以在发布页面指定保存路径
String olapFolderOnServer = request.getParameter("olapFolderOnServer"),
if(olapFolderOnServer != null){
session.setAttribute("olapFolderOnServer",olapFolderOnServer);
}
调用aly.toString()
方法可以获取到报表定义的 JSON 串,程序员同样可以自行将其保存到数据中。
直接使用数据源做报表分析存在一个问题,由于分析界面也能查明细,需要把所有数据查出后再在报表中汇总,数据量大时可能很慢甚至卡死。所以通常建议使用时先查询过滤,整理好数据集后再进行分析。