开源olap:mondrian/jpivot 【持续更新】

April 5th, 2010 by ahuoo Leave a reply »

上周花了好些时间去研究这两个玩意,了解了OLAP的基本原理,学习了一下OLAP查询语言MDX标准,下面是关于MDX的官方解释:

MDX was introduced by Microsoft with Microsoft SQL Server OLAP Services in around 1998, as the language component of the OLE DB for OLAP API. More recently, MDX has appeared as part of the XML for Analysis API. Microsoft proposed MDX as a standard, and its adoption among application writers and other OLAP providers is steadily increasing.

最终把mondrian/jpivot集成到了我们项目中,在此列出遇到的几个困难:

1、如何统一数据源集成。 因为官方demo数据源的指定有两种方式,一种是基于JDNI,需要在tomcat里面配置,另外一种就是要在jsp里面指定,每次都要指定,对于项目,这种做法肯定是不可取的,后来我通过修改 jp:mondrianQuery标签的定义类解决了此问题, 关于数据库的一系列配置,可以通过ServetContext来保存传递。


2、可定制性报表界面展示。场景描述:当一个用户登录,用户会点开一些节点查看数据,如果发现此展示视图符合自己的要求,用户可以保存此视图,下次登录后打开此报表,会直接看到当时所保存的视图。当然这样对一些一般不发生变化维度数据是可取的,如果经常变化,还是另想办法。至于怎么做的就是存储MDX语句就ok,+ 主要要修改jpivot这一层(方法MondrianModel.getResult())。


3、mondrian缓存清理。mondrian的缓存机制相当了得,具体可以看下面的官方文档,为了提高查询效率,所以将所有数据都加载到缓存里面,但这个给调试带来了不便,如果修改了事实表和维表的数据,查询依然还是之前的数据,大家可以通过CacheControl这个类来控制,我做了个缓存清理功能,主要为了生产环境调试用,但只能对于新连接管用,用户必须关闭浏览器重新建立连接才得行,更加的复杂的控制我们可一起探讨 O(∩_∩)O~

4、jpivot钻取数据的格式化。在利用jpivot钻取的时候,发现出来的数字数据都精确到了小数点后两位,我可不想所有数字都这么精确,连带出来的id值也被这样格式化了,悲惨!查阅了官方文档,实现了Level标签中的formatter属性,但是依然没用,后来发现这么一个文件:config.xml, 其实通过配置这个文件可以对某些数据进行格式化定义,貌似国际化没有中文,大家改成修改默认配置就ok。

5、定制jpivot钻取的数据并导出。在利用jpivot钻取的时候,发现钻取的明细数据都是设置好的Level值,但是我想显示一些非Level的值并到出到excel,因为每次点钻取明细数据的时候,其实Jivot都会递交一条SQL去后台查询,我最终的做法是截获此SQL的条件,然后自己拼装好需要查出来的字段,完美解决了! 截获SQL的类在DrillThroughUI.DrilThroughHandler.request , MondrianDrillThrough.drillThrough(Cell),有了SQL,至于导出你自己另外做了!

6、定制mondrian数据权限。情景:我希望olap报表对于admin,可以查看所有地区的销售额,但对于北方区的用户lily则只能查看北方区的销售业绩,这就需要数据级的权限控制了。 mondrian的权限控制有2种,一种是固定的配置,另外一种可以通过编程动态指定,即动态赋予用户某些权限,具体需要修改的地方是:MondrianModel.initialize()里面设置角色的地方。 怎么动态设置角色,可以查看mondrian源代码里面的方法:AccessControlTest.getRestrictedConnection(boolean restrictCustomers),还是给个例子吧:

    //ahuoo
    RoleImpl role = new RoleImpl();
    Schema schema = monConnection.getSchema();
    final boolean fail = true;
    Cube salesCube = schema.lookupCube("Sales", fail);
    final SchemaReader schemaReader = salesCube.getSchemaReader(null);

    Hierarchy storeHierarchy = salesCube.lookupHierarchy(
             new Id.Segment("Customers", Id.Quoting.UNQUOTED), false);
    role.grant(schema, Access.ALL_DIMENSIONS);
    role.grant(salesCube, Access.ALL);

    Level nationLevel = Util.lookupHierarchyLevel(storeHierarchy, "Country");
    Role.RollupPolicy rollupPolicy = Role.RollupPolicy.HIDDEN;

    role.grant(storeHierarchy, Access.CUSTOM, nationLevel, null, rollupPolicy);    

    role.grant(schemaReader.getMemberByUniqueName(
                   Util.parseIdentifier("[Customers].[USA].[WA]"), fail), Access.ALL);

    //使Member   [Customers].[USA].[WA].[Anacortes]无法访问
    role.grant(schemaReader.getMemberByUniqueName(
                 Util.parseIdentifier("[Customers].[USA].[WA].[Anacortes]"), fail), Access.NONE);

    //Prevents any further modifications
    role.makeImmutable();

    //设置角色
    monConnection.setRole(role);


对于新手,可能不知道mondrian jpivot到底是什么?我这里解释一下:
mondrian :是olap服务器,负责olap模型到关系数据库的映射,简单的说就是实现了MDX标准,可以将MDX语句转换成关系数据库中的一套。

jpivot: 简单的说就是个展示工具,把mondrian传来的xml数据渲染成我们熟悉的html,对于层次性很强的报表,xml渲染的确有他的魅力,免去了繁杂的js痛苦,画个整个数据流程图吧

oracle/mysql ———->mondrian———->jpivot

这里给个官方的学习文档地址:
http://mondrian.pentaho.org/documentation/olap.php

Advertisement

5 comments

  1. yang says:

    jpivot钻取数据的格式化。???这个是怎么做的

    • ahuoo says:

      在包的com.tonbeller.wcf.format这个目录下面有个配置文件config.xml,因为没有中文版,所以读取的是默认配置,你把默认的pattern改哈就可以了

  2. yang says:

    望指教 谢谢

  3. sky says:

    我报了一个异常,Caused by: org.apache.commons.beanutils.NestedNullException: Null property value for ‘propertyConfig’
    at org.apache.commons.beanutils.PropertyUtilsBean.getNestedProperty(PropertyUtilsBean.java:669)
    at org.apache.commons.beanutils.PropertyUtilsBean.getProperty(PropertyUtilsBean.java:715)
    at org.apache.commons.beanutils.PropertyUtils.getProperty(PropertyUtils.java:290)
    at com.tonbeller.wcf.expr.ExprUtils.getModelReference(ExprUtils.java:87)
    at com.tonbeller.wcf.controller.RequestContextImpl.getModelReference(RequestContextImpl.java:106)
    at com.tonbeller.wcf.toolbar.ScriptButtonModel.isPressed(ScriptButtonModel.java:38)
    at com.tonbeller.wcf.toolbar.ToolButton.render(ToolButton.java:114)
    at com.tonbeller.wcf.toolbar.ToolBar.render(ToolBar.java:77)
    at com.tonbeller.wcf.component.NestableComponentSupport.render(NestableComponentSupport.java:39)
    at com.tonbeller.wcf.component.RendererTag.doEndTag(RendererTag.java:137)
    at org.apache.jsp.testpage_jsp._jspx_meth_wcf_005frender_005f0(testpage_jsp.java:1186)
    at org.apache.jsp.testpage_jsp._jspService(testpage_jsp.java:185)
    … 69 more

    不知道这是不是哪儿没有配置对还是因为我使用了spring scurity的原因,麻烦您指点一下啊,谢谢

    • ahuoo says:

      把你的testpage.jsp里面的这一句给去掉试试

      wcf:scriptbutton id=”propertiesButton” tooltip=”toolb.properties” img=”properties” model=”#{table01.rowAxisBuilder.axisConfig.propertyConfig.showProperties}”

Leave a Reply