Es la implementación de la capa lógica usando Mondrian REST para Datachile.
Contiene la configuración del esquema de cubos y provee el entrypoint REST de la API para consultas.
Documentación completa para crear un schema aquí: Mondrian Schema
bundle install
jruby -G -S jbundle install
jruby -S gem install jbundler
config.yaml.example
bajo el nombre config.yaml
y completar los datos.JRUBY_OPTS=-G MONDRIAN_REST_CONF=
pwd/config.yaml MONDRIAN_REST_SECRET=lala JAVA_OPTS="-Dlog4j.configuration=file:log4j.properties -Dmondrian.olap.SsasCompatibleNaming=true" rackup
moncat -d frags/ -o schema.xml
Ejecutar los comandos anteriormente descritos puede resultar una labor tediosa cada vez que se realicen modificaciones en frags
, teniendo que reiniciar el servidor. Se sugiere crear un archivo de script, que permita tener todos los comandos necesarios para iniciar el servidor.
init.sh
, y agregar los comandos necesarios para inicializar (como sugerencia, primero moncat
y luego rackup
)chmod +x init.sh
./init.sh
Luego de estas etapas, a futuro sólo basta ejecutando ./init.sh
.
Descripción y ejemplos de las palabras clave en Mondrian y OLAP.
En el siguiente diagrama se puede apreciar un ejemplo de cubo en donde existen 3 dimensiones:
En la intersección de los ejes -cubos celestes- está la measure agregada y el valor definido que estamos buscando en este query.
fact_
y tablas dim_
El diagrama de estrella para una base de datos relacional organiza la información pensando en que:
fact
: los hechos. Las measures y datos a ser agregados más los campos de referencia tidy son parte de esta tabla.dimensiones
relacionadas. Estas dimensiones serán mapeadas en el schema.xml
y puedem ser compartidas entre varios cubos -como el caso de la dimensión geográfica-.Las dimensiones puede ser definidas en una tabla y mapear los campos que respondan a los ids y los nombres, por ejemplo la dimensión Geography
:
<Dimension name="Geography">
<Annotations>
<Annotation name="index_as">geo</Annotation>
</Annotations>
<Hierarchy hasAll="true" primaryKey="id">
<Table name="dim_comunas" schema="public"/>
<Level column="region_id" name="Region" nameColumn="region_name" uniqueMembers="true"/>
<Level column="comuna_datachile_id" name="Comuna" nameColumn="comuna_name" uniqueMembers="true"/>
</Hierarchy>
</Dimension>
... o bien -sin son pequeñas- pueden ser definidas como tablas inline
como por ejemplo la dimensión Sex
:
<Dimension name="Sex">
<Annotations>
<Annotation name="es_element_caption">Sexo</Annotation>
</Annotations>
<Hierarchy hasAll="true" primaryKey="sex_id">
<InlineTable alias="dim_sex">
<ColumnDefs>
<ColumnDef name="sex_id" type="Numeric"/>
<ColumnDef name="description" type="String"/>
<ColumnDef name="es_description" type="String"/>
</ColumnDefs>
<Rows>
<Row>
<Value column="sex_id">0</Value>
<Value column="description">No data</Value>
<Value column="es_description">No informa</Value>
</Row>
<Row>
<Value column="sex_id">2</Value>
<Value column="description">Male</Value>
<Value column="es_description">Masculino</Value>
</Row>
<Row>
<Value column="sex_id">1</Value>
<Value column="description">Female</Value>
<Value column="es_description">Femenino</Value>
</Row>
</Rows>
</InlineTable>
<Level column="sex_id" name="Sex" nameColumn="description" uniqueMembers="true" caption="Sex">
<Annotations>
<Annotation name="es_caption">Description ES</Annotation>
<Annotation name="es_element_caption">Sexo</Annotation>
</Annotations>
<Property column="es_description" name="Description ES"/>
</Level>
</Hierarchy>
</Dimension>
En general la decisión estará basada en la cantidad de members
que tenga esa dimensión.
Repetir datos puede ser un detalle sin importancia en las tablas dim_
dado que OLAP siempre hará agregaciones. Pero puede multiplicarse si se necesita multilenguaje. Es la única manera de hacerlo: tener las dimensiones -y sus niveles- en varios idiomas en campos separados. Se indica el campo dentro de cada Level
utilizando Annotations
y Property
.
Ejemplo de Dimension
inline sobre grados de discapacidad:
<Dimension foreignKey="disability_grade" name="Disability Grade">
<Annotations>
<Annotation name="es_element_caption">Grado de discapacidad</Annotation>
</Annotations>
<Hierarchy hasAll="true">
<InlineTable alias="disability_grade">
<ColumnDefs>
<ColumnDef name="id" type="Numeric"/>
<ColumnDef name="description" type="String"/>
<ColumnDef name="es_description" type="String"/>
</ColumnDefs>
<Rows>
<Row>
<Value column="id">1</Value>
<Value column="description">No disability</Value>
<Value column="es_description">Sin discapacidad</Value>
</Row>
<Row>
<Value column="id">2</Value>
<Value column="description">Slight to moderate</Value>
<Value column="es_description">Leve a moderada</Value>
</Row>
<Row>
<Value column="id">3</Value>
<Value column="description">Severe</Value>
<Value column="es_description">Severa</Value>
</Row>
</Rows>
</InlineTable>
<Level column="id" name="Disability Grade" nameColumn="description" uniqueMembers="true">
<Annotations>
<Annotation name="es_caption">Description ES</Annotation>
</Annotations>
<Property column="es_description" name="Description ES"/>
</Level>
</Hierarchy>
</Dimension>
Luego en el query habrá que solicitar el caption
al drilldown
basado en el nombre de la property
.
Otros conceptos necesarios para comprender la manera de realizar queries:
Drilldown: Pasar de un nivel de detalle al siguiente:
Cut: Filtrar y cortar el cubo seleccionado:
Maule
y Antofagasta
.X
.Asia
.Colombia
.# Dimensiones solicitadas por las cuales combinar miembros y agregar:
drilldown[]: [Origin Country].[Country].[Country]
drilldown[]: [Geography].[Geography].[Comuna]
drilldown[]: [Date].[Date].[Year]
# Medida de la cual deseo agregación
measures[]: CIF US
# Cortes a los datos por determinados años. (opcional)
cut[]: {[Date].[Date].[Year].&[2013], [Date].[Date].[Year].&[2014], [Date].[Date].[Year].&[2015]}
# Agrego otro corte, sólo para la región 1
cut[]: [Geography].[Geography].[Region].&[1]}
Para más detalle de la manera de realizar queries: Mondrian REST.
Mondrian REST
.Mondrian REST
.