Mondrian

Mondrian es un motor OLAP de bases de datos.

Se puede descargar desde sourceforge y forma parte del proyecto pentaho

Instalación

Si lo descargas, descomprimes e intentas usar desde Linux puedes seguir la documentación en español que hay en el directorio doc del paquete que te has bajado. Que es una copia de la documentación on line

Sólo comentarte que si pretendes usarlo con MySql como yo puede que tengas problemas. Por lo que si los tienes y no puedes importarlos puedes usar este dump que he descargado de aqui

Una vez tienes la base de datos ya puedes seguir las instrucciones normales. ( esto es un resumen)

  • Presupongo que ya tienes intalado TOMCAT
  • Dejas el mondrian.war en webapps y lo despliegas ( o esperas a que tomcat lo haga automaticament o reinicias tomcat)
  • Modificas el fichero mondrian.properties para indicarle cual es el driver jdbc. ( pon el jdbc de MySql en el directorio lib de Tomcat si no lo tienes ya)
  • Modificas el fichero web.xml que hay en WEB-INF para actualizar el driver. Es decir cambias:
    Provider=mondrian;Jdbc=jdbc:odbc:MondrianFoodMart;Catalog=/WEB-INF/queries/FoodMart.xml;JdbcDrivers=sun.jdbc.odbc.JdbcOdbcDriver;

por esto otro

    Provider=mondrian;Jdbc=jdbc:mysql://localhost/foodmart?user=foodmart;password=foodmart;Catalog=/WEB-INF/queries/FoodMart.xml;JdbcDrivers= com.mysql.jdbc.Driver;
  • Ahora sólo tienes que acutalizar los ficheros fourheir.jsp, mondrian.jsp, colors.jsp y arrows.jsp situados en el directorio WEB-INF/queries para indicarle el nuevo driver. Es decir esto:
    <jp:mondrianQuery id="query01" jdbcDriver="sun.jdbc.odbc.JdbcOdbcDriver" jdbcUrl="jdbc:odbc:MondrianFoodMart" catalogUri="/WEB-INF/queries/FoodMart.xml">

Por esto otro:

    <jp:mondrianQuery id="query01" jdbcDriver="com.mysql.jdbc.Driver" jdbcUrl="jdbc:mysql://localhost/foodmart?user=foodmart&password=foodmart" catalogUri="/WEB-INF/queries/FoodMart.xml">

Y listo…. reinicas tomcat para que se entere de los cambios y a disfrutar : http://localhost:8080/mondrian

Configuración

mondrian.properties

Ubicado bajo WEB-INF contiene la configuración básica de mondrian. Puedes encontrar una explicación extensa aqui

Y aqui está el listado de todas las propiedades que puedes especificar.

Las más importanets:

  • Catalog : Donde se encuentra el fichero con el esquema XML
  • JdbcDrivers : pos eso…. tu driver Jdbc
  • La cadena de conexión

Un ejemplo de mondrian.properties para MySql:

# Allow the use of aggregates
mondrian.rolap.aggregates.Use=true
mondrian.rolap.aggregates.Read=true
mondrian.native.topcount.enable=true
mondrian.native.filter.enable=true

# mondrian.properties
mondrian.result.limit=50000

Provider=mondrian;Jdbc=jdbc:mysql://localhost/foodmart?user=foodmart;password=foodmart;Catalog=/WEB-INF/queries/FoodMart.xml;JdbcDrivers= com.mysql.jdbc.Driver;

El esquema Mondrian

En efecto, FoodMart.xml es el esquema mondrian que nos viene en nuestro ejemplo. En el podemos ver casi todo lo que puede haber en un esquema.

Un esquema es la definición de la base de datos multi-dimensional. Contiene el modelo lógico, los cubos, las jerarquías, los niveles, y el mapeo de estos elementos contra la base de datos relacional ( modelo físico)

El modelo lógico nos permite hacer la abstracción a MDX.

El esquema no es mas que un archivo XML. Los elementos mas importantes a la hora de crear un esquema son las dimensiones, medidas y cubos

  • Una dimension es un atributo o conjunto de atributos mediante los cuales puedes dividir las medidas en sub-categorías. Por ejemplo bebidas alcoholicas.
  • una medida es una cantidad que estas interesado en medir. Por ejemplo las ventas
  • Un cubo es una colecciones de diemsiones y medidas. Por ejemplo ventas de bebidas alcoholicas

Dimensión

Dentro de la etiqueta dimensión se especifica todo lo referente a una dimensión. Una dimensión se especifica por medio de una jerarquía compuesta por miembros.

  • Un miembro es un punto de una determinada dimensión de un determinado nivel de una jerarquía. La jerarqía género tiene un nivel y dos miembros masculino y femenino.
  • Una jeraquia es un conjunto de miembros ordenados que permiten agrupamiento. Por ejemplo país, región, ciudad.
  • Un nivel es un conjunto de miembros similares.
  • Una dimensión es una colección de jerarquías

Veamos un ejemplo simple:

    <Dimension name="Genero" foreignKey="id_persona">
      <Hierarchy hasAll="true" primaryKey="id_persona">
      <Table name="persona"/>
        <Level name="Genero" column="sexo" uniqueMembers="true"/>
      </Hierarchy>
    </Dimension> 

Como puedes ver esta dimensión consiste en una jerarquía que tiene un único nivel llamado genero. La tabla origen de esta jerarquía es persona. El valor, los miembros de esta jeraquía vienen de la columna sexo de esta tabla.

Una dimensión está unida a un cubo por 2 colúmnas, una en la tabla de hechos y la otra en la tabla de dimensión. El elemento <Dimension> contiene la clave foránea ubicada en la tabla de hechos. que es la que nos permitirá relacionar el cubo con la dimensión

Por defecto cada jearquía contiene un nivel en la cima que llamaremos ALL. Que contiene un único nivel llamado TODO {nombre de la jerarquía}. Este elemento es el padre de todos los demás miembros de la jerarquía.

Si la jerarquía no tiene un único elemento en la cima se ha de poner el atributo hasAll a false ( hasAll=“false” ). En ese caso el miembro por defecto de esa dimensión será el primero del primer nivel. Por ejemplo, en la jerarquía tiempo sería el primer año. El nivel padre es el nivel por defecto. Aunque esto se puede modificar con el atributo defaultMember

veamos un ejemplo mas completo:


<Dimension name="Store">

<Hierarchy hasAll="true" primaryKey="store_id">
 <Table name="store"/>
 <Level name="Store Country" column="store_country" uniqueMembers="true"/>
 <Level name="Store State" column="store_state" uniqueMembers="true"/>
 <Level name="Store City" column="store_city" uniqueMembers="false"/>
 <Level name="Store Name" column="store_name" uniqueMembers="true">
  <Property name="Store Type" column="store_type"/>
  <Property name="Store Manager" column="store_manager"/>
  <Property name="Store Sqft" column="store_sqft" type="Numeric"/>
  <Property name="Grocery Sqft" column="grocery_sqft" type="Numeric"/>
  <Property name="Frozen Sqft" column="frozen_sqft" type="Numeric"/>
  <Property name="Meat Sqft" column="meat_sqft" type="Numeric"/>
  <Property name="Has coffee bar" column="coffee_bar" type="Boolean"/>
  <Property name="Street address" column="store_street_address" type="String"/>
 </Level>
 </Hierarchy>
</Dimension>

Cubo

El cubo no es otra cosa que una enumeración de miembros de jerarquías y hechos. Un cubo se suele apoyar en una tabla de hechos que sirve como base de calculo. La idea es construir un cubo imaginario que nos permita movernos por los datos a traves de la combinación de sus cardinalidades. Algo parecido a esto:

La tabla de hechos se especifica:

<Cube name="Mi_Cubo">
  <Table name="Mi_Tabla_De_Hechos"/>
...
</Cube> 

En un cubo se almacenan medidas, hechos que tambien hay que especificar. Eso se hace de la siguiente forma:

<Cube name="Mi_Cubo">
  <Table name="Mi_Tabla_De_Hechos"/>
  ...
  <Measure name="Unit Sales" column="unit_sales" aggregator="sum" datatype="Integer" formatString="#,###"/>
  <Measure name="Store Sales" column="store_sales" aggregator="sum" datatype="Numeric" formatString="#,###.00"/>
...
</Cube> 

De esta manera se establece el comportamiento de cada miembro, Su nombre, la columna de la tabla en la que se basa, como se agrega , el tipo de dato que es y el formato

Tipo de datos

El tipo de dato por defecto es Numeric aunque puede ser:

  • String
  • Integer
  • Numeric
  • Boolean
  • Date
  • Time
  • Timestamp

Lector SQL

Como que una medida proviene de una tabla, una medida puede tener un “lector SQL” que indique en que forma se debe leer.

Ejemplo:

<Measure name="Promotion Sales" aggregator="sum" formatString="#,###.00">
 <MeasureExpression>
  <SQL dialect="generic">
   (case when sales_fact_1997.promotion_id = 0 then 0 else sales_fact_1997.store_sales end)
  </SQL>
 </MeasureExpression>
</Measure> 

Dimensiones del Cubo

Las dimensiones que existen en un cubo pueden ser epecificadas tanto dentro del propio cubo como fuera. Si se usa una dimensión ”Externa” se utiliza la etiqueta <DimensionUsage> donde se le da un nombre, se hace referencia al nombre original de la dimensión ”Externa” y se le indica cual será la columna por la que se hará el vinculo ( el join, la clave foranea)

 <DimensionUsage name="Store Type" source="Store Type" foreignKey="warehouse_store_id"/>

Por otro lado, tambien es posible especificar la dimensión dentro del cubo:

<Cube name="Sales 2">
	<Table name="sales_fact_1997"/>
	<!-- dimension definida fuera del cubo -->
	<DimensionUsage name="Time" source="Time" foreignKey="time_id"/>
	<DimensionUsage name="Product" source="Product" foreignKey="product_id"/>

	<!-- dimension definida dentro  del cubo -->
	<Dimension name="Gender" foreignKey="customer_id">
		<Hierarchy hasAll="true" allMemberName="All Gender" primaryKey="customer_id">
			<Table name="customer"/>
			<Level name="Gender" column="gender" uniqueMembers="true"/>
		</Hierarchy>
	</Dimension>

	<!-- medidas  del cubo -->
	<Measure name="Sales Count" column="product_id" aggregator="count" formatString="#,###">
		<CalculatedMemberProperty name="MEMBER_ORDINAL" value="1"/>
	</Measure>

	<Measure name="Unit Sales" column="unit_sales" aggregator="sum" formatString="Standard">
		<CalculatedMemberProperty name="MEMBER_ORDINAL" value="2"/>
	</Measure>

	<Measure name="Store Sales" column="store_sales" aggregator="sum" formatString="#,###.00">
		<CalculatedMemberProperty name="MEMBER_ORDINAL" value="3"/>
	</Measure>

	<Measure name="Store Cost" column="store_cost" aggregator="sum" formatString="#,###.00">
		<CalculatedMemberProperty name="MEMBER_ORDINAL" value="6"/>
	</Measure>

	<Measure name="Customer Count" column="customer_id" aggregator="distinct-count" formatString="#,###">
		<CalculatedMemberProperty name="MEMBER_ORDINAL" value="7"/>
	</Measure>

	<CalculatedMember name="Profit" dimension="Measures">
		<Formula>
		[Measures].[Store Sales] - [Measures].[Store Cost]
		</Formula>
		<CalculatedMemberProperty name="FORMAT_STRING" value="$#,##0.00"/>
		<CalculatedMemberProperty name="MEMBER_ORDINAL" value="4"/>
	</CalculatedMember>

	<CalculatedMember name="Profit last Period" dimension="Measures" formula="COALESCEEMPTY((Measures.[Profit], [Time].PREVMEMBER),    Measures.[Profit])" visible="false">
		<CalculatedMemberProperty name="MEMBER_ORDINAL" value="5"/>
	</CalculatedMember>
</Cube>

Interacción con el cubo

Una vez que tenemos un cubo definido querremos interactuar con el. Para ello mondrian usa Jpivot. se ve algo así como esto.

Cache

Mondrian es un motor OLAP hibrido. Puede basarse en BBDD o puede tener los datos en cache. Si tu sistema refresca los datos frecuentemente puede que te interese desabilitar la cache.

Esto se hace en la definición del cubo. Al definir un cubo mondiran defines si tiene o no cache.

<Cube name="MiCubo" cache="false" enabled="true">
		<Table name="miTabla">
		</Table>
		<DimensionUsage source="dimension1" name="dimension1" foreignKey="id_dimension1">
		</DimensionUsage>
		<DimensionUsage source="dimension2" name="dimension2" foreignKey="id_dimension2">
		</DimensionUsage>
		<Measure name="Numero" column="numero" datatype="Numeric" aggregator="sum">
		</Measure>
	</Cube>
 
olap/mondrian.txt · Última modificación: 2009/07/19 22:22 por juantxu
 
Excepto donde se indique lo contrario, el contenido de esta wiki se autoriza bajo la siguiente licencia:CC Attribution-Noncommercial-Share Alike 3.0 Unported
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki