olap分析平台的设计与实现(四)--mondrian schemal

开源OLAP引擎:Mondrian OLAP Created 星期四 20 十月 2016为了满足业务管理和决策的报表系统(包括传统报表、数据仓库、OLAP等)也被创建出来,企业主管通过报表了解企业的总体运行状态。但是,随着企业间竞争的加剧和市场节奏的进一步加快,企业的日常管理需要对关键业务指标的更加实时的监控和反馈。比如:制造业需要更及时的仓库调度、金融业需要更实时的风险防范、电信业需要更及时的服务指标监控。于是,越来越多的企业 阅读详情

本文重点总结mondrian4 schemal的写法及其趟过的各种坑,我的mondrian版本是4.7.0.0-12

不涉及雪花模型、共享维、Virtual cubes,attribute的property、Closure tables、聚合、调优 等,总结最基础的schemal,毕竟财政业务相对是比较简单的。

olap发展一直不太好,我觉得很重要的原因就是schemal等的原因,再加上展示麻烦。mdx很容易,弄过sql的人,搞mdx倒是蛮快的。

3.X的schemal:可参考 BI中如何配置模式文件(Schema)一文

和数据库连接弄好了,我们当然是为了查询需要的数据。我们先利用OLAP4J的query对象的,进行相关查询。

查询前我理解最好校验一下,olap4j文档上说,校验做了3件事情:

1)Performs default selections 执行默认选择

2)Validates the presence of at least one dimensions on both ROWS and COLUMNS

       axis  校验在行、列轴上是否存在至少一个维度

3)Tries to build a MDX parse tree 尝试构建MDX分析树

我们开始Creating selections to include or exclude from a query:

做这件事情,其实是2步:

1、找基准点

2、基于基准点进行操作

        // olap4j的mdx接口,是一个jdbc实现,推荐
        System.out.println("\r\n===================olap4j接口==================");
        String mdxStr = "select {[年].Members} on columns,{[组织].Members} on rows from 模型一";
        // 建立连接
        String strUrl = "jdbc:mondrian:";
        strUrl += "Jdbc=" + url;
        strUrl += ";JdbcUser=" + userName;
        strUrl += ";JdbcPassword=" + password;
        // strUrl += ";Catalog=" + xmlFile;
        strUrl += ";CatalogContent=" + getCatalogContent();
        Class.forName("mondrian.olap4j.MondrianOlap4jDriver");
        Connection olap4jConn = DriverManager.getConnection(strUrl);
        OlapConnection olapConn = (OlapConnection) olap4jConn.unwrap(OlapConnection.class);
        NamedList<Cube> cubes =
                olapConn.getOlapSchema().getCubes();
        Cube cube = cubes.get("模型一");
        Query myQuery =
                new Query("model1Query", cube);
        myQuery.execute();
       System.out.println("------------myQuery------------:"+myQuery);
        QueryDimension year = myQuery.getDimension("Year");
        QueryDimension entity = myQuery.getDimension("Entity");
        myQuery.getAxis(Axis.COLUMNS).addDimension(year);
        myQuery.getAxis(Axis.ROWS).addDimension(entity);
        Member year2017 =
                cube.lookupMember(
                        IdentifierNode.ofNames ("Year", "2017年")
                                .getSegmentList());
        year.include(year2017);
        myQuery.validate();
        System.out.println(
                myQuery.getSelect().toString());

        String s=myQuery.getSelect().toString();
        System.out.println("s:"+s);

        CellSet cellSet =   myQuery.execute();
        // 输出结果
        CellSetFormatter formatter = new RectangularCellSetFormatter(false);
        formatter.format(cellSet, new PrintWriter(System.out, true));

执行结果:

SELECT
{[Year].[2017年]} ON COLUMNS,
{[Entity].[All Entitys]} ON ROWS
FROM [模型一]
s:SELECT
{[Year].[2017年]} ON COLUMNS,
{[Entity].[All Entitys]} ON ROWS
FROM [模型一]
10:13:36.394 [mondrian.rolap.RolapResultShepherd$executor_2] DEBUG mondrian.spi.impl.JdbcDialectImpl - JdbcDialectImpl.getType Dialect- ORACLE, Column-COUNT(DISTINCT"YEAR") is of internal type INT. JDBC type was 2.  Column precision=0.  Column scale=0
10:13:36.462 [mondrian.rolap.agg.SegmentCacheManager$sqlExecutor_2] DEBUG mondrian.spi.impl.JdbcDialectImpl - JdbcDialectImpl.getType Dialect- ORACLE, Column-c0 is of internal type OBJECT. JDBC type was -9.  Column precision=20.  Column scale=0
10:13:36.462 [mondrian.rolap.agg.SegmentCacheManager$sqlExecutor_2] DEBUG mondrian.spi.impl.JdbcDialectImpl - JdbcDialectImpl.getType Dialect- ORACLE, Column-c0 is of internal type OBJECT. JDBC type was -9.  Column precision=20.  Column scale=0
10:13:36.462 [mondrian.rolap.agg.SegmentCacheManager$sqlExecutor_2] DEBUG mondrian.spi.impl.JdbcDialectImpl - JdbcDialectImpl.getType Dialect- ORACLE, Column-m0 is of internal type OBJECT. JDBC type was 2.  Column precision=0.  Column scale=0
10:13:36.462 [mondrian.rolap.agg.SegmentCacheManager$sqlExecutor_2] DEBUG mondrian.spi.impl.JdbcDialectImpl - JdbcDialectImpl.getType Dialect- ORACLE, Column-c0 is of internal type OBJECT. JDBC type was -9.  Column precision=20.  Column scale=0
10:13:36.462 [mondrian.rolap.agg.SegmentCacheManager$sqlExecutor_2] DEBUG mondrian.spi.impl.JdbcDialectImpl - JdbcDialectImpl.getType Dialect- ORACLE, Column-c0 is of internal type OBJECT. JDBC type was -9.  Column precision=20.  Column scale=0
10:13:36.462 [mondrian.rolap.agg.SegmentCacheManager$sqlExecutor_2] DEBUG mondrian.spi.impl.JdbcDialectImpl - JdbcDialectImpl.getType Dialect- ORACLE, Column-m0 is of internal type OBJECT. JDBC type was 2.  Column precision=0.  Column scale=0
10:13:36.462 [mondrian.rolap.agg.SegmentCacheManager$sqlExecutor_2] DEBUG mondrian.spi.impl.JdbcDialectImpl - JdbcDialectImpl.getType Dialect- ORACLE, Column-c0 is of internal type OBJECT. JDBC type was -9.  Column precision=20.  Column scale=0
10:13:36.462 [mondrian.rolap.agg.SegmentCacheManager$sqlExecutor_2] DEBUG mondrian.spi.impl.JdbcDialectImpl - JdbcDialectImpl.getType Dialect- ORACLE, Column-c0 is of internal type OBJECT. JDBC type was -9.  Column precision=20.  Column scale=0
10:13:36.462 [mondrian.rolap.agg.SegmentCacheManager$sqlExecutor_2] DEBUG mondrian.spi.impl.JdbcDialectImpl - JdbcDialectImpl.getType Dialect- ORACLE, Column-m0 is of internal type OBJECT. JDBC type was 2.  Column precision=0.  Column scale=0
|             | 2017年       |
+-------------+-------------+
| All Entitys | 79440368.57 |

为进一步测试,我写4个测试程序:

测试程序测试foodmart例子。(用mondrian与olap4j分别实现)

一个测试程序测试非税(用mondrian与olap4j分别实现);

用mondrian4的规范重写一遍非税与foodmart的schemal。

再原来的3.0版本基础上,重写了,报错:

RolapSchema$MondrianSchemaException: Dimension 'Year' not found in this cube, but there is a schema dimension of that name. Did you intend to create cube dimension referring to that schema dimension? (in ForeignKeyLink) (at line 42, column 10)

原来可能是是3.0引用方式,4.0中schemal不认识它们?

动手按4.0文档的内容重新写schemal如下:

<?xml version="1.0" encoding="UTF-8"?>
<Schema name="OlapSchema" metamodelVersion="4.0">

  <PhysicalSchema>
    <Table name="C1_FACT"/>
    <Table name="C1_DIM_YEAR"/>
    <Table name="C1_DIM_ACCOUNT"/>
    <Table name="C1_DIM_ENTITY"/>
    <Table name="C1_DIM_PERIOD"/>
  </PhysicalSchema>

  <Cube name="模型一" defaultMeasure="金额">


    <Dimensions>
      <Dimension name="Year"  table="C1_DIM_YEAR" key="Id" >
        <Attributes>
          <Attribute  name="Id"  keyColumn="ID"  hasHierarchy='false'/>
           <Attribute  name="YearName"   hasHierarchy='false'>
             <Key>
               <Column name="YEAR"/>
             </Key>
          </Attribute>
          <!--和上面是等价的写法-->
          <!--<Attribute  name="YearName"   keyColumn="YEAR" hasHierarchy='false'/>-->

        </Attributes>
        <Hierarchies>
          <Hierarchy name="YearLy" hasAll="true">
            <Level attribute="YearName"/>
          </Hierarchy>
        </Hierarchies>
      </Dimension>

      <Dimension name="Period" table="C1_DIM_PERIOD"  key="Id">
        <Attributes>
          <Attribute  name="Id"  keyColumn="ID" columnName="ID" />
          <Attribute  name="Year"  keyColumn="ID" columnName="YEAR" />
          <Attribute  name="Quarter"  keyColumn="ID" columnName="QUARTER"  />
          <Attribute  name="Month"  keyColumn="ID" columnName="MONTH"/>
        </Attributes>
        <Hierarchy name="Period" hasAll="false" defaultMember="[Period].[全年合计].[4季].[12]" >
          <Level attribute="Year"/>
          <Level attribute="Quarter"/>
          <Level attribute="Month"/>
        </Hierarchy>
      </Dimension>

      <Dimension name="Entity" table="C1_DIM_ENTITY" key="Id">
        <Attributes>
          <Attribute  name="Id"  keyColumn="ID"  hasHierarchy='false'/>
          <!--以下写法逻辑上是否是错误的?-->
          <!--方法1-->
<!--          <Attribute  name="Province" keyColumn="LEVEL_1" hasHierarchy='true'>
          </Attribute>-->
          <!--方法2-->
           <!-- <Attribute  name="Province"  keyColumn="ID" columnName="LEVEL_1" hasHierarchy='true'/>-->
          <!--方法3-->
          <Attribute  name="Province"  column="LEVEL_1" hasHierarchy='true'>
            <Key>
              <Column table="C1_DIM_ENTITY" name="ID"/>
              </Key>
          </Attribute>


          <Attribute  name="City" keyColumn="ID" columnName="LEVEL_2"  hasHierarchy='true'>
          </Attribute>
          <Attribute  name="Country" keyColumn="ID" columnName="LEVEL_3"  hasHierarchy='false'>
          </Attribute>
        </Attributes>

        <Hierarchies>
          <Hierarchy name="EntityLy" hasAll="true">
            <Level attribute="Province"/>
            <Level attribute="City"/>
            <Level attribute="Country"/>
          </Hierarchy>
        </Hierarchies>
      </Dimension>
    </Dimensions>

    <MeasureGroups>
      <MeasureGroup name="C1_FACT" table="C1_FACT">
        <Measures>
          <Measure name="金额" column="V_1" aggregator="sum" visible="true" formatString="0.########"/>
        </Measures>
        <DimensionLinks>
          <ForeignKeyLink dimension="Year" foreignKeyColumn="YEAR"/>
          <ForeignKeyLink dimension="Entity" foreignKeyColumn="ENTITY"/>
          <ForeignKeyLink dimension="Period" foreignKeyColumn="PERIOD"/>
        </DimensionLinks>
      </MeasureGroup>
    </MeasureGroups>
  </Cube>
</Schema>

抛出错误:

Exception in thread "main" mondrian.rolap.RolapSchema$MondrianSchemaException: Attribute must have a key (in Attribute 'YearName') (at line 16, column 10)

shcemal中,属性修改如下:

<Attribute  name="Id"  keyColumn="ID"  hasHierarchy='false'/>,就不报告这个错误了。(上面已经改过了,原来写的column=)

另外,上面2个红框内容要一致。否则,报错如下:

 Key attribute 'ID' is not a valid attribute of this dimension (in Dimension 'Entity') (at line 27, column

schemal写好了,olap4j query 成功。

用mdx再测试一遍:

String mdxStr = "select {[Year].Members} on columns,{[Entity].Members} on rows from 模型一";

报错:

mondrian.olap.MondrianException: Mondrian Error:The 'Entity' dimension contains more than one hierarchy, therefore the hierarchy must be explicitly specified.

修改mdx:

String mdxStr = "select {[Year].Members} on columns,{[Entity].[EntityLy].[湖北省财政厅]} on rows from 模型一";

ok!结果如下:

写4.0schemal,我是基于2个文档的:

一个是4.0官方文档

一个是Mondrian 4规范文章(网上搜的)

进一步用Query对象查询前,我们先总结一下mondrain4.0schemal。

整体结构:见官方文档的2.1 Structure of a Schema 

A cube (see <Cube>) is a named collection of dimensions and measures.

measure:

  schemal中,别名定义:可以用于用户自定义属性?

  measure当中的caption属性,可以用于返回标题?

  table中,可以加入计算列,度量定义中,可以使用计算列。

  • An attribute is a value, possessed by every fact, by which you can divide facts into subsets. For example, you might wish to break down product sales by their color, the gender of the customer, and the store in which the product was sold; color, gender, and store are all attributes.
  • A dimension is a grouping of related attributes. For example, name, gender, zip code and eye color are attributes of the customer dimension; color, weight, and manufacturer are attributes of the product dimension.

属性的 key column then <Key> and keyColumn are equivalent

<key>元素和 attribute的属性 keyColumn,是等价的,看个人偏好 ?这个没有理解,反正key就是为和数据库匹配吧,如果不写keycolum,总报错。

对这个事情没有把握?那就用foodmart数据库重新写一个schemal

4.0文档的例子,也是报错Attribute must have a key ...

文档中是:

<Attribute name="Month" column="month_of_year">

<Key>

<Column name="the_year"/>

<Column name="month_of_year"/>

</Key>

</Attribute>

修改后是:

<Attribute name="Month" keyColumn="MONTH_OF_YEAR"/>

官文中间的<key>是啥作用,不是很了解。

官文中说:

Variations in syntax between different databases is handled by specifying more than one <Key> element:

和数据库有关?

For example, if you are defining an attribute with a simple (non-composite) key you could either write

<Attribute name="A">

<Key>

<Column name="c">

</Key>

</Attribute>

or

<Attribute name="A" column="c"/>

a simple (non-composite) key 的确是这样的。

复合键的写法如下:什么情况下用复合键呢,这个问题先留着。

If the attribute has a composite key, or if you wish to use the table attribute, you have to use the nested <Key> element:

<Attribute name="A">

<Key>

 <Column table="t1" name="c1"/>

 <Column table="t2" name="c2"/>

</Key>

</Attribute>

反正都和数据库有关。

attribute是什么意思呢,对我们的应用而言,它是必须的吗 我3.0的schemal没有写一个attribute呢。这个好像是3.0和4.0的一个明显不同的的地方。

官文推荐先写attribute,attribute的先后顺序也是查询结果的先后顺序?

看看文档的解释:

Parent elementAttributeEquivalent nested elementDescription
<Attribute>keyColumn<Key>Column(s) that comprise the key of this attribute.构成该属性关键字的列(数据库当中的字段)。
<Attribute>nameColumn<Name>Column that defines the name of members of this attribute. If not specified, the attribute key is used.定义此属性成员名称的列。如果未指定,则使用属性键。Column就是数据库字段名?
<Attribute>orderByColumn<OrderBy>Column(s) that define the order of members. If not specified, the attribute key is used.
<Attribute>captionColumn<Caption>Column that forms the caption of members. If not specified, the attribute name is used.
<Measure>column<Arguments>Column(s) that are the arguments to this measure. (When this measure is implemented by generating a SQL expression, these columns become the argument to the SQL aggregate function.)
<Table>keyColumn<Key>Column(s) that form this Table's key.
<Link>foreignKeyColumn<ForeignKey>Column(s) that form a foreign key from this Link's referencing table to its referenced table.
<ForeignKeyLink>foreignKeyColumn<ForeignKey>Column(s) that form a foreign key from a measure group's fact table to a dimension table.

keyColumn与nameColumn:我理解都是数据库字段,区别在于,一个是key column,一个就是这个属性的column

Attribute name must be specified 这个错误的解决:

RolapSchema$MondrianSchemaException: Attribute name must be specified. (Name can only be omitted when key contains a single column.) (in Attribute 'Province')

原因是我的配置文件:

          <Attribute  name="Province" column="LEVEL_1" hasHierarchy='true'>
           <Key>
              <Column name="ID"></Column>
              <Column name="LEVEL_1"></Column>
            </Key>
        </Attribute>

测试了三种写法,都可以解决这个报错:

          <!--以下写法逻辑上是否是错误的?-->
          <!--方法1-->
<!--          <Attribute  name="Province" keyColumn="LEVEL_1" hasHierarchy='true'>
          </Attribute>-->
          <!--方法2-->
           <!-- <Attribute  name="Province"  keyColumn="ID" columnName="LEVEL_1" hasHierarchy='true'/>-->
          <!--方法3-->
          <Attribute  name="Province"  column="LEVEL_1" hasHierarchy='true'>
            <Key>
              <Column table="C1_DIM_ENTITY" name="ID"/>
              </Key>
          </Attribute>

keyColumn到底绑定那个列呢,我感到有2种选择,实际出了问题再调整不迟,反正不是key 就是colum。,我目前的看法是:用key可以在数据库中确认唯一一条记录。

Atrr元素的columnName、column有啥区别呢,没明白?问题先留着。

Inherited attributes

Hierarchy是层次结构的重点:

By default, every hierarchy contains a top level called '(All)', which contains a single member called '(All {hierarchyName})'. This member is parent of all other members of the hierarchy, and thus represents a grand total.

默认情况下,每个层次结构都包含一个名为'(All)'的顶级,其中包含一个名为'(All {hierarchyName})'的成员。 该成员是层次结构中所有其他成员的父成员,因此代表总计。

If the <Hierarchy> element has hasAll="false", the 'all' level is suppressed. The default member of that dimension will now be the first member of the first level; for example, in a Time hierarchy, it will be the first year in the hierarchy. Changing the default member can be confusing, so you should generally use hasAll="true".

借用google翻译:

如果<Hierarchy>元素具有hasAll =“false”,则“全部”级别将被抑制。 该维度的默认成员现在将是第一级别的第一个成员; 例如,在时间层次结构中,它将是层次结构中的第一年。 更改默认成员可能会造成混淆,因此通常应使用hasAll =“true”。

You can also set the default member of a hierarchy explicitly. The defaultMember attribute should be the fully-qualified name of the default member.

<Hierarchy name="Yearly" hasAll="false" defaultMember="[Time].[1997].[Q1].[1]">

...

</Hierarchy>

When specified in this way, the default member can even be a calculated member.

这个对我们有点用,财务上经常有期初、期末的概念:

先动手在schemal中增加一段配置

      <Dimension  table="C1_DIM_PERIOD"  key="Id">
        <Attributes>
          <Attribute  name="Id"  keyColumn="ID"  />
          <Attribute  name="Year"  keyColumn="YEAR" />
          <Attribute  name="Quarter"  keyColumn="QUARTER" />
          <Attribute  name="Month"  keyColumn="MONTH" />
        </Attributes>
        <Hierarchy name="期间" hasAll="true" >
          <Level attribute="Year"/>
          <Level attribute="Quarter"/>
          <Level attribute="Month"/>
        </Hierarchy>
      </Dimension>

运行测试,报错:

Exception in thread "main" java.lang.NullPointerException
	at mondrian.olap.Util.quoteMdxIdentifier(Util.java:490)
	at mondrian.rolap.RolapSchemaLoader.getOrCreateDimension(RolapSchemaLoader.java:2703)

维度中添加:

再运行,报错:

.RolapSchema$MondrianSchemaException: table 'C1_DIM_PERIOD' not found (in Dimension 'Period') (at line 27, column 6)

检查,dimession有table属性,再看发现问题,修改如下:

  <PhysicalSchema>
    <Table name="C1_FACT"/>
    <Table name="C1_DIM_YEAR"/>
    <Table name="C1_DIM_ACCOUNT"/>
    <Table name="C1_DIM_ENTITY"/>
    <Table name="C1_DIM_PERIOD"/>
  </PhysicalSchema>

PhysicalSchema中增加C1_DIM_PERIOD的说明。

再运行,ok!

修改dimession:

        <Hierarchy name="Period" hasAll="false" defaultMember="[Period].[全年合计].[4季].[12]" >
          <Level attribute="Year"/>
          <Level attribute="Quarter"/>
          <Level attribute="Month"/>
        </Hierarchy>

修改了期间的默认值? 有什么用途,后面再说。

ps1:关于uniqueMembers的设置

uniqueMembers属性用于优化SQL生成。如果你已经知道在维表中level列的值在这个层次的父级是唯一的,可以设置uniqueMembers=”true”,否则设置为"false”。例如时间维[Year].[Month]在[Month]这个level,应该设置uniqueMembers=”false”,因为同样的月可以出现在不同的年。在另一方面,假设有[Product Class].[Product Name]层次,你可以确保[Product Name]是唯一的,就可以设置uniqueMembers=”true”。如果并不能确定,则先设置为false。一般在最顶级,经常是设置为true,因为没有父层次。

引用自:https://blog.youkuaiyun.com/wonder4/article/details/4833641 

ps2:level,到层次根有同样距离层次的成员的集合。

ps3:包含type属性的Level,值可以设置为String,Integer,Numeric,Boolean,Date,Time和Timestamp。默认是Numeric,因为主键列一般为数值类型。如果类型不同,Mondrian需要知道正确的类型以便生成SQL,例如String值会生成用单引号包含的语句.

我一直没有用type.mondrian3好像用的多,是不是因为现在的level都是引用的attribute?
 

mondrian4时间维度:

MDX相关时间的函数:

  • ParallelPeriod([level[, index[, member]]])
  • PeriodsToDate([level[, member]])
  • WTD([member])
  • MTD([member])
  • QTD([member])
  • YTD([member])
  • LastPeriod(index[, member])

ps:schemal中,表名、数据库列名全部是大写(oracle的原因);

schemal中,属性名称一般是首字母大写,其余小写。

本文结尾:我针对非税开票明细再写一个schemal:

事实表:fact_col_trade_detail,记录开票信息明细表,这个表记录了松滋2009年到2017年间全部开票信息。

我们只分析维度只选取收费项目、时间,度量维只选择金额、笔数,考虑到这个表本记录的事明细数据,每条记录就是一个项目一次收费情况,可以把笔数看成退化维度? 

不过,我这里先把这个也看成一个度量,增加一个字段no,  执行update fact_col_trade_detail t set t.no=1。

接下来,我来准备项目维度:

项目维度:维度表是: dim_chargeproject

时间维度:有2种思路:

一个参照foodmart例子,构建时间维度;

另外一个是把时间拆分为年度、期间2个维度;我们分别实现这2种维度:

dim_date:这个维度标中,最小日期是2005年,最大日期是2020年。

事实表中CHARGEDATE_KEY 与datakey相应。

另外一个时间维度体系是年度、与期间:这里先只搞个年度维度表DIM_YEAR_COLTRADE:和事实表中的year_key相关联。

下面是schemal:

<?xml version="1.0" encoding="UTF-8"?>
<Schema name="OlapSchema" metamodelVersion="4.0">

  <PhysicalSchema>
    <Table name="FACT_COL_TRADE_DETAIL">
    </Table>

    <Table name="DIM_CHARGEPROJECT">
      <Key>
        <Column name='PROJECTKEY'/>
      </Key>
    </Table>

    <Table name="DIM_DATE">
      <Key>
        <Column name='DATEKEY'/>
      </Key>
    </Table>
    <Table name="DIM_YEAR_COLTRADE">
      <Key>
        <Column name='YEARKEY'/>
      </Key>
    </Table>
  </PhysicalSchema>

  <Cube name="Col_trade_detail" defaultMeasure="金额">


    <Dimensions>

      <Dimension name="Year"  table="DIM_YEAR_COLTRADE" key='Year_key' >
        <Attributes>
          <Attribute name='Year_key' keyColumn='YEARKEY' hasHierarchy='false'/>
          <Attribute name='YearString' keyColumn='YEAR' hasHierarchy='false'/>
          <Attribute name='Yearname' keyColumn='YEARNAME' hasHierarchy='false'/>
        </Attributes>
        <Hierarchies>
          <Hierarchy name='YearLy' allMemberName='All Year'>
            <Level attribute='Yearname'/>
          </Hierarchy>
        </Hierarchies>
      </Dimension>
      <Dimension name='Time' table='DIM_DATE' type='TIME' key='Time Id'>
      <Attributes>
        <Attribute name='Year' keyColumn='THE_YEAR' levelType='TimeYears' hasHierarchy='false'/>
        <Attribute name='Quarter' levelType='TimeQuarters' hasHierarchy='false'>
          <Key>
            <Column name='THE_YEAR'/>
            <Column name='DATEOFQUATER'/>
          </Key>
          <Name>
            <Column name='DATEOFQUATER'/>
          </Name>
        </Attribute>
        <Attribute name='Month' levelType='TimeMonths' hasHierarchy='false'>
          <Key>
            <Column name='THE_YEAR'/>
            <Column name='MONTH_OF_YEAR'/>
          </Key>
          <Name>
            <Column name='MONTH_OF_YEAR'/>
          </Name>
        </Attribute>
<!--        <Attribute name='Week' levelType='TimeWeeks' hasHierarchy='false'>
          <Key>
            <Column name='the_year'/>
            <Column name='week_of_year'/>
          </Key>
          <Name>
            <Column name='week_of_year'/>
          </Name>
        </Attribute>-->
        <Attribute name='Day' levelType='TimeDays' hasHierarchy='false'>
          <Key>
            <Column name='DATEKEY'/>
          </Key>
          <Name>
            <Column name='DAY_OF_MONTH'/>
          </Name>
          <OrderBy>
            <Column name='DATEKEY'/>
          </OrderBy>
        </Attribute>
        <Attribute name='Month Name' hasHierarchy='false'>
          <Key>
            <Column name='THE_YEAR'/>
            <Column name='MONTH_OF_YEAR'/>
          </Key>
          <Name>
            <Column name='THE_MONTH'/>
          </Name>
        </Attribute>
        <Attribute name='Date' keyColumn='FULLDATE' hasHierarchy='false'/>
        <Attribute name='Time Id' keyColumn='DATEKEY' hasHierarchy='false'/>
      </Attributes>

        <Hierarchies>
          <Hierarchy name='Time' hasAll='false'>
            <Level attribute='Year'/>
            <Level attribute='Quarter'/>
            <Level attribute='Month'/>
          </Hierarchy>
        </Hierarchies>

      </Dimension>

      <Dimension name="Account" table="DIM_CHARGEPROJECT"  key="Projectkey">
        <Attributes>
          <Attribute  name="Projectkey"  keyColumn="PROJECTKEY" hasHierarchy='false'>
          </Attribute>
          <Attribute name='Level1projectname'  hasHierarchy='false'>
            <Key>
              <Column name='LEVEL1PROJECTCODE'/>
            </Key>
            <Name>
              <Column name='LEVEL1PROJECTNAME'/>
            </Name>
          </Attribute>
          <Attribute name='Level2projectname'  hasHierarchy='false'>
            <Key>
              <Column name='LEVEL1PROJECTCODE'/>
              <Column name='LEVEL2PROJECTCODE'/>
            </Key>
            <Name>
              <Column name='LEVEL2PROJECTNAME'/>
            </Name>
          </Attribute>
          <Attribute name='Level3projectname'  hasHierarchy='false'>
            <Key>
              <Column name='LEVEL1PROJECTCODE'/>
              <Column name='LEVEL2PROJECTCODE'/>
              <Column name='LEVEL3PROJECTCODE'/>
            </Key>
            <Name>
              <Column name='LEVEL3PROJECTNAME'/>
            </Name>
          </Attribute>
          <Attribute name='Level4projectname'  hasHierarchy='false'>
            <Key>
              <Column name='LEVEL1PROJECTCODE'/>
              <Column name='LEVEL2PROJECTCODE'/>
              <Column name='LEVEL3PROJECTCODE'/>
              <Column name='LEVEL4PROJECTCODE'/>
            </Key>
            <Name>
              <Column name='LEVEL4PROJECTNAME'/>
            </Name>
          </Attribute>
          <Attribute name='Level5projectname'  hasHierarchy='false'>
            <Key>
              <Column name='LEVEL1PROJECTCODE'/>
              <Column name='LEVEL2PROJECTCODE'/>
              <Column name='LEVEL3PROJECTCODE'/>
              <Column name='LEVEL4PROJECTCODE'/>
              <Column name='LEVEL5PROJECTCODE'/>
            </Key>
            <Name>
              <Column name='LEVEL5PROJECTNAME'/>
            </Name>
          </Attribute>
          <Attribute name='Level6projectname'  hasHierarchy='false'>
            <Key>
              <Column name='LEVEL1PROJECTCODE'/>
              <Column name='LEVEL2PROJECTCODE'/>
              <Column name='LEVEL3PROJECTCODE'/>
              <Column name='LEVEL4PROJECTCODE'/>
              <Column name='LEVEL5PROJECTCODE'/>
              <Column name='LEVEL6PROJECTCODE'/>
            </Key>
            <Name>
              <Column name='LEVEL6PROJECTNAME'/>
            </Name>
          </Attribute>
          <Attribute name='Level7projectname' hasHierarchy='false'>
            <Key>
              <Column name='LEVEL1PROJECTCODE'/>
              <Column name='LEVEL2PROJECTCODE'/>
              <Column name='LEVEL3PROJECTCODE'/>
              <Column name='LEVEL4PROJECTCODE'/>
              <Column name='LEVEL5PROJECTCODE'/>
              <Column name='LEVEL6PROJECTCODE'/>
              <Column name='LEVEL7PROJECTCODE'/>
            </Key>
            <Name>
              <Column name='LEVEL7PROJECTNAME'/>
            </Name>
          </Attribute>
        </Attributes>

        <Hierarchies>
          <Hierarchy name='Account_L' allMemberName='All Account' >
            <Level attribute="Level1projectname"/>
            <Level attribute="Level2projectname"/>
            <Level attribute="Level3projectname"/>
            <Level attribute="Level4projectname"/>
            <Level attribute="Level5projectname"/>
            <Level attribute="Level6projectname"/>
            <Level attribute="Level7projectname"/>
          </Hierarchy>
        </Hierarchies>
      </Dimension>
    </Dimensions>

    <MeasureGroups>
      <MeasureGroup name="FACT_COL_TRADE_DETAIL" table="FACT_COL_TRADE_DETAIL">
        <Measures>
          <Measure name="金额" column="AMT" aggregator="sum" visible="true" formatString="0.########"/>
        </Measures>
        <DimensionLinks>
          <ForeignKeyLink dimension="Year" foreignKeyColumn="YEAR_KEY"/>
          <ForeignKeyLink dimension="Account" foreignKeyColumn="CHARGEPROJECT_KEY"/>
          <ForeignKeyLink dimension="Time" foreignKeyColumn="AUDITDATE_KEY"/>
        </DimensionLinks>
      </MeasureGroup>
    </MeasureGroups>
  </Cube>
</Schema>

参考文档:

Mondrian 4规范文章_学无耻境的博客-优快云博客

ps:

上一节:部署foodmart例子

下一节:olap4j入门

 

九、OLAP之多维分析 实际上,Mondrian并不会一开始就将的所有的数据从数据库Load到内存中,而是随着不断的钻取而执行不同的查询,它的执行速度等同于我们sql的执行速度,其展现的数据与我们的业务设计相关,除非我们要一次性从数据库中查询出几十万甚至上百万条数据,否则,效率问题是可以不考虑的。prefix为前缀,suffix为后缀,再结合传入的query,整合起来就是 /WEB-INF/queries/AccessInfo.jsp,接着打开该文件,即通过mdx实现。用户可以执行典型的OLAP导航,如下钻、切片。 阅读详情

相关推荐

TwinCAT3 实时核异步通信:基于ADS的C++ Server/Client数据交换实战解析

本文深入解析了在TwinCAT3实时核中,如何利用ADS协议实现C++ Server与Client之间的异步数据交换。文章从核心概念入手,详细阐述了实时核、ADS通信及异步机制,并通过实战步骤指导环境搭建、路由配置、Server端服务创建与Client端请求发起,重点剖析了Req/Ind/Res/Con异步回调模型,旨在帮助开发者构建高效、非阻塞的实时工业控制应用。

purple的博客 467

olap分析平台的设计与实现(十七)- springboot集成mondrian

开发环境搭建: 1个想法一通向导搞定spring boot ps:使用IDEA构建一个SpringBoot + Hibernate + Gradle项目 这一步,算是建造了spring + hibernate,后面还有连接池,换成mybatis的问题。 idea中Alt + Enter导入包,和eclipse有点不一样。 甲骨文罐子??:ps: gradle开发springboot项目...

wh_xia_jun的专栏 2282

SAP中MRP运行计划行超限问题的分析与解决

SAP中基于生产性物料的采购特点,通常会采用采购计划协议的方式进行采购。其具体的采购计划通常来自于成品计划独立需求,然后通过物料清单,经由MRP跑出。 在采购计划协议中的计划行中,存在一个计划行号,随着MRP在不断跑出新的计划行,该行号资源会消耗完。当计划行号消耗完后,MRP不会再跑出新的计划行。且在MD04或MD02中看不到类似提示信息。此时可以通过MD05来查看是否出现类似下图的提示信息。 ...

专注SAP应用技术文章写作,致力于拉近用户与系统间的距离; 3842

Mondrian开源OLAP引擎详解

Mondrian是一个基于Java语言的开源OLAP引擎,它通过MDX语句执行查询,从关系型数据库RDBMS中读取数据,然后经过Java API以多维度的形式展示查询结果。Mondrian是一个OpenSource的基于关系数据库的分析服务器,遵循MDX、XML/A和JOLAP标准。Mondrian的架构Mondrian从架构上可以分为四个层次:表现层、计算层、聚合层、存储层。表现层:指最终呈现在...

赵英超的博客 7499

薛定谔 | 先导化合物优化与相互作用可视化

当获得针对某个靶点的先导分子后,想要在此基础上进行化学结构修饰。为了提升化学改造的成功率可以采用本教程方法进行结构虚拟改造/优化。每用薛定谔处理一个新任务,第一步必须创建新的project以方便日后管理。选项卡中修改工作路径(可以方便地找到输出文件)

药研猿的博客 2143

C#通过Aforge调用电脑摄像头(附代码)

C#标准库本身不带有能调用电脑摄像头的库,如果利用windows自身的API来实现的话,着实有些麻烦。Aforge这个第三方库能很好的实现调用、处理的功能。 PS:文末给大家分享了完整的项目源码,各位最好先下载下来,对照着来看 1、先看一下效果 2、Aforge介绍 AForge.NET是一个专门为开发者和研究者基于C#框架设计的,这个框架提供了不同的类库和关于类库的资源,还有很多应用程序例子,包括计算机视觉与人工智能,图像处理,神经网络,遗传算法,机器学习,机器人等领域。 3、我使用的开发环境 操作系统

weixin_44996090的博客 1万+

【亲测免费】 Mondrian OLAP: 提供高性能的数据分析解决方案

Mondrian OLAP: 提供高性能的数据分析解决方案 Mondrian OLAP 是一个开源的在线分析处理 (OLAP) 引擎,可帮助您快速分析大量数据。它是一个用于构建多维数据库并提供灵活、高效查询功能的工具。借助 Mondrian OLAP,您可以创建复杂的多维数据集,并为您的业务用户提供交互式数据分析体验。 项目介绍 Mondrian OLAP 的主要目标是提供一种易于使用的接口,以便...

gitblog_00074的博客 511

基于ABCDRez的激光谐振腔设计与热透镜效应仿真实践

本文详细介绍了如何利用ABCDRez代码包进行激光谐振腔设计与热透镜效应仿真。通过ABCD矩阵理论和高斯光束q参数,该工具能有效模拟热透镜动态变化对腔稳定性的影响,指导腔型优化与热补偿设计,是固体激光器预研与调试的高效辅助手段。

weixin_29093017的博客 288

Mondrian简介

出自:https://www.cnblogs.com/lk-fxtx/p/7067720.html 一、 Mondrian简介 Mondrian是一个开源项目。一个用Java写成的OLAP引擎。它用MDX语言实现查询,从关系数据库(RDBMS)中读取数据。然后经过javaAPI以多维的方式对结果进行展示。 Mondrian的使用方式同JDBC驱动类似。可以非常方便的与现有的Web项目集成...

HouYing 9878

VECTOR硬件VN1600系列对比:VN1610、VN1611、VN1630A、VN1640A、VN1630log、VN1670

VN16系列说不清道不明的区别和关系

AmorRun的博客 2万+

南京理工大学计算机预推免面试(双非重点关注)

南京理工大学总体来说对双非学校比较友好,上岸率比较高,而且面试形式是线上,在预推免的过程中,可以作为重点关注的学校,但是一定要注意南理报名截止的时间,部分学校可能保研名额公示的比较晚,对于保研边缘人来说很可能会错过,我的建议是,即使不确定能否拿到保研名额,先查一下截止时间,先在系统上报名!!一旦拿到了offer,就是铁的,保底专硕,而且有很大的技巧性,一定要认真看哈!!!每个人的情况可能都不一样,如果有需要帮忙可以私我~~~

D1379951481的博客 2017

mondrian olap 示例_Mondrian入门系列(七)OLAP基本操作

本章是系列(四)中组装MDX的扩展。切片、切块可以通过MDX实现,一般添加在filter轴。例如添加Time.1997,Store.Store City钻取钻取即是把Level替换为member,如TIme.Year –>Time.1997旋转加上query.swapAxes()即可就是交换行列。过滤如选取Unit Sales>1000的,QueryAxis qa.filter(“[M...

weixin_36413157的博客 690

基于卷积神经网络的遥感图像地物分类

AI:89-基于卷积神经网络的遥感图像地物分类 基于卷积神经网络的遥感图像地物分类是一个令人兴奋的领域,它在环境监测、城市规划、农业、国防等领域具有广泛的应用。深度学习技术为我们提供了更准确、高效的工具,有望在未来进一步提高分类性能。在本文中,我们探讨了卷积神经网络的工作原理、数据准备、模型构建、训练和评估过程,并提供了多个代码示例。此外,我们讨论了地物分类的应用和挑战,以及未来的发展趋势。

一键难忘的博客 2717

olap分析平台的设计与实现(五)-olap4j

本节重点总结olap4j开发 根据上一章节的schemal,我们用olap4j方式实现查询。 package com.muge.as.dao; import mondrian.olap.Util; import org.olap4j.Axis; import org.olap4j.CellSet; import org.olap4j.OlapConnection; import org.o...

wh_xia_jun的专栏 1498

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Mondiran创建连接

mondrian创建连接的过程,不包括如何加载schema内容。

Hello World 2434

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Mondrian入门系列(二)获取连接

获取连接import mondrian.olap4j.MondrianOlap4jConnection; import java.sql.Connection; //注意包别导错了Class.forName("mondrian.olap4j.MondrianOlap4jDriver"); Connection connection = DriverManager.getConnection( "jd

1046

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

多维数据模型总结和归纳

开源OLAP引擎:Mondrian 在Mondrian里面的cube是以XML的形式定义的。(MDX) Mondrian本身是不存储数据的,通过MDX语句(一个类似于SQL的查询语言)来获取数据,Mondrian 运行的时候要连数据库,并且还要有一个数据模型配置文件(Mondrian叫schema),其实就是一个取数据的规则;由此可知Mondrian只不过是把MDX 翻译成了SQL然后从数据库中...

Joe192的博客 6176

探索数据深渊:mondrian-olap 开源项目全面解析

探索数据深渊:mondrian-olap 开源项目全面解析 在数据分析的海洋中,如何高效地提取和分析复杂的多维数据一直是技术挑战。今天,我们将深入探讨一个强大的开源工具——mondrian-olap,它以其独特的技术架构和广泛的应用场景,为数据分析师和开发者提供了一个强大的多维数据查询解决方案。 项目介绍 mondrian-olap 是一个基于 JRuby 的 gem,它集成了 Mondrian ...

gitblog_00357的博客 949

Mondrian 3.0.4 学习总结

Mondrian 是一个用 Java 写成的 OLAP 引擎,是开源项目 Pentaho 的一部分。它实现了 MDX 语言、XML 解析、JOLAP 规范。它从 SQL 和其它数据源读取数据并把数据聚集在内存缓存中,然后经过 Java API用多维的方式对结果进行展示,同时可以不写 SQL就能分析存储于 SQL 数据库的庞大数据集,可以封装 JDBC数据源并把数据以多维的方式展现出来。

zhangzhongzhong的博客 7421

Mondrian-OLAP: 探索数据的多维度分析利器

Mondrian-OLAP: 探索数据的多维度分析利器 项目基础介绍及编程语言 Mondrian-OLAP 是一个基于 JRuby 的开源项目,它整合了强大的 Mondrian OLAP 引擎,允许开发者使用 Ruby 语言来执行对关系型数据库数据的复杂多维查询。此项目特别适用于那些希望以更直观的方式分析大量数据集的用户和开发者。项目源码托管在 GitHub,并采用 MIT 和 EPL-1.0 许...

gitblog_00408的博客 812

Mondrian API

Mondrian API Created 星期一 24 十月 2016 http://mondrian.pentaho.com/api/index.htmlMondrian 是一个独立的引擎,一般都是通过嵌入到应用的方式来使用它,只需要在类路径加个类库就可以。实际上有多套BI 解决方案都是通过集成Mondrian 的方式来实现多维分析。本章介绍编程方式连接Mondrian,执行MDX 查询的

小小懒羊羊 3258

mondrian olap 示例_Mondrian数据库olap应用文档

Mondrian数据库olap应用文档一 创建数据仓库1)DW名称主要是在相应数据库中建立相应的数据仓库,事实表,维表结构2)选择数据源主要是应用weblogic 控制台,建立数据库连接池、数据源并进行数据源的选择例如:建立数据源jdbc/LnSw在weblogic控制台中配置数据库连接池和数据源,其中数据源的格式如jdbc/xxxx表示;如:在纳税评估系统中数据源格式为jdbc/Lnsw3) 设...

weixin_30280259的博客 270

Mondrian OLAP前端

OLAP前端 Created 星期一 24 十月 2016 Mondrian 本身基本只是一个OLAP 引擎,它也包含Jsp 标签库、MdxQueryServlet可以生成静态的HTML 表格,但比较简单,而且需要提供MDX 语句。如果需要丰富的展示效果以及用户交互能力,可以选用一个前端工具。 JPIVOT jPivot 是一个老牌的前端展示工具。可以参考,但界面太丑。 saiku

小小懒羊羊 1754

探索audio-diffusion的无限可能:音频插值与风格迁移技术详解

audio-diffusion是一个基于Hugging Face diffusers包的创新项目,它将扩散模型应用于音乐合成领域,突破了传统扩散模型仅用于图像生成的局限。本文将深入解析其两大核心功能——音频插值与风格迁移技术,带您领略AI音乐创作的全新可能。 ## 什么是audio-diffusion? audio-diffusion项目通过将扩散模型从图像领域迁移到音频领域,实现了基于AI的

gitblog_00094的博客 450

数据仓库---JPivot连接MySQL VS PostgreSQL

JPivot是一个基于mondrian(OLAP分析服务)的可钻取web报表展示标签,形成了整套的较方便的数据仓库主题web展现工具。话说JPivot已经很久没有更新了,作为小规模的应用,试试可以,但是要做为产品,貌似还差太多。下面以JPivot连接Mysql VS PostgreSQL做个简单的例子,以比较两个数据库有什么差别,作为分析比较之用。 数据准备 1. 建立数据库和表 CREAT

数据时代--收集,存储,处理,分析,挖掘,检索,展现 2247

从零开始构建终极跨平台curl:你的网络工具箱革命

你是否曾经因为Windows上curl版本过时而烦恼?或者因为系统依赖问题导致curl命令在不同机器上表现不一?今天,我要向你介绍curl-for-win项目——这不仅仅是一个简单的curl二进制包,而是一个完整的、可重现的构建生态系统,让你的网络操作从此告别兼容性烦恼。 想象一下:你开发了一个脚本,在本地运行完美,但部署到服务器上却因为curl版本差异而崩溃。这种经历相信很多开发者都遇到过。c

gitblog_01025的博客 777
上一篇: mondrian in action 第一章翻译 (主要用百度翻译完成,稍加整理)
下一篇: mondrian in action 第二章 Mondrian: a first look(未完成全部翻译)
wh_xia_jun
博客等级 码龄16年 1335粉丝 405原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值