Consultas multidatasources-datadiscovery en Gadget Template

ES | EN

En algunas ocasiones, para poder crear un gadget template que satisfaga tus necesidades, necesitas poder acceder a más de un datasource. Para esto se han implementado varias funciones:

vm.getDataFromDataSource(datasource,callbackFunction,filters,group,project,sort,limit,offset,param,debug) 

Los tres primeros parámetros están disponibles en versiones antiguas, y el resto son soportados a partir de la versión "Empire". Todas estas operaciones se aplican en servidor transformando la query del datasource.

  • datasource: identificador del datasource al que quieres acceder. Ten en cuenta que sólo devolverán datos a los que el usuario tenga acceso. En el caso de que quieras mostrar un dashboard público, las ontologías de las cuales se forman los datasources también deben estar marcadas como públicas.
  • callbackFunction: función que retornará los datos tras la consulta. Al definirla, tan sólo necesita un parámetro, que será el que nos devuelva los datos.
  • filters: puedes pasar un array de filtros para los datos. Un ejemplo de filtros sería éste, donde se pasan dos: [{field: f.field1,op: "=",exp: f.value1},{field: f.field2,op: "=",exp: f.value2}], en el que field es el path del parametro del datasource, por ejemplo 'Helsinki.year', op es el operador que puede ser =,>,<, in ..., y exp es el valor.
    • Ejemplo filtro tipo IN: Si tienes un array de strings con los elementos por los que quieres filtrar, puedes crear un array que contenga todos los filtros por si usas más de uno, y después pasar esta variable a la consulta, por ejemplo: 
var elementosSeleccionados = ['elemento1',elemento2','elemento4'];

var filtros = [];

filtros.push({field: 'campoDeLaEntidadPorElQueFiltrar',op: "IN",exp: "('" + elementosSeleccionados.join("', '") + "')"});

En el caso de que fueran valores numéricos no pondríamos las comillas simples.

vm.from(datasource).filters(filtros).exec...
  • group: array de strings para los campos de agrupación del datasource. Para que sea coherente, estos campos deben estar también en la etapa project. Si no se necesita (pero sí hay parámetros posteriores), se puede pasar el valor en vacío, []
  • project: indica la proyección aplicada al datasource y se compone de un array de JSON de dos campos {"field":"field/projectop","alias":"alias"} definiendo cada proyección con su alias (no requerido), por ejemplo [{"field":"Restaurant.cuisine"}] ó [{"field":"Restaurant.cuisine","alias":"cui"}]. Si se tienen campos tipo group, deberán ir como proyección. Si no se necesita (pero si hay parámetros posteriores), se puede pasar el valor en vacío []
  • sort: indica la ordenación que se aplica al datasource y se compone de un array de JSON dos campos {"field":"fieldtosort","asc":true/false}. Por ejemplo, una ordenación descendiente valida es ésta; [{"field":"Restaurant.cuisine","asc":false}]. Si no se necesita (pero si hay parámetros posteriores) se puede pasar el valor en vacío []
  • offset: indica el offset aplicado al datasource. Es un valor entero. Si no se necesita (pero si hay parámetros posteriores), se puede pasar el valor -1
  • limit: indica el límite aplicado al datasource. Es un valor entero. Si no se necesita (pero si hay parámetros posteriores), se puede pasar el valor -1
  • param: se pueden incluir parámetros en el datasource para, por ejemplo, sustituir dentro de una subquery un valor o la parte que se requiera. Hay que tener en cuenta que este parámetro habilita un inyección SQL, por lo que hay que usarlo de forma controlada. El parámetro en el datasource vendrá definido con la notación {$param}, por ejemplo:
SELECT t1.pt as pt
FROM 
(select * from translations) as t1,
(select * from translations) as t2
where t1.{$cdest}=t2.id

Se compone de un array de JSON con dos campos {"field":"paramtoverwrite","value":"value"}, por ejemplo: [{"field":"cdest","value":"United States"}]

  • debug: sólo habilitado para el modo desarrollo (para visualización habrá que quitarlo). Por defecto a false. Si se habilita la respuesta del motor, devuelve la query generada para su depuración.


Realizaremos a continuación un ejemplo de uso:

Crea inicialmente dos datasources, uno con la ontología HelsinkiPopulation y otro con la ontología Restaurants:

En un dashboard, crea un gadget template.

Accede a la edición del gadget:

y escribe en la caja de texto de HTML:

<!-- Write your HTML <div></div> and CSS <style></style> here -->

<!--Focus here and F11 to full screen editor--> 

<h2>HELSINKIDATA </h2>
{{vm.helsinkiData}} 

<br><h2>RESTAURANTSDATA </h2>
{{vm.restaurantsData}} 


y en la caja de texto JAVASCRIPT:

//Write your controller (JS code) code here

//Focus here and F11 to full screen editor


//This function will be call once to init components
vm.initLiveComponent = function(){   
   vm.getDataFromDataSource('helsinki',vm.callbackFunctionHelsinki,[{field:'Helsinki.year',op:'=',exp:'2000'}]);
   vm.getDataFromDataSource('restaurants',vm.callbackFunctionRestaurants);
}; 


vm.callbackFunctionHelsinki = function (data){ 
  vm.helsinkiData = data;
  console.log(vm.helsinkiData);
}

vm.callbackFunctionRestaurants = function (data){ 
  vm.restaurantsData = data;
  console.log(vm.restaurantsData);
}

//This function will be call when data change. On first execution oldData will be null
vm.drawLiveComponent = function(newData, oldData){
};

//This function will be call on element resize
vm.resizeEvent = function(){

}

//This function will be call when element is destroyed
vm.destroyLiveComponent = function(){

};



En el caso de que desees pasar una cadena en el filtro, pásala escapando las comillas de esta forma: exp:'\'TEXTO\'' 

Para hacer un filtro sobre fechas, puedes usar este formato: [{field: 'FECHA', op: '<=' , exp: "TIMESTAMP('2011-01-02T00:00:00.000Z')"}]


Datasource API Chaining y operaciones con promise (a partir de la versión Empire):

A partir de la versión 1.6.0-Empire, se dispone la posibilidad de usar un API más ágil, basada en promesas. Desde cualquier template, tienes las siguientes operaciones:

  • vm.get('datasource',params): sólo se tiene requerido el id del datasource. Params será una estructura JSON con todas las operaciones embebidas, por ejemplo:

{"limit":3,"offset":4}

Se devuelve una promesa por lo que se puede operar con la misma por ejemplo:

vm.get("DsRawRestaurants").then(
	data => console.log(data)
)

o (si se necesita retrocompatibilidad con navegadores antiguos)

vm.get("DsRawRestaurants").then(
	function(data){
		console.log(data)
	}
)
  • vm.getOne('datasource'): caso especial del anterior (vm.get(datasourcename,{"limit":1})) en el que sólo se quiere un valor .
  • vm.from('datasource')...: con esta función, accederás al Api Chaining de los datasource que también devuelve una promesa. Tiene esta estructura:

vm.from(datasource).(chaining operations).exec();

Las "chaining operations" corresponden con todas las operaciones sobre los datasources y se usan para componer la estructura de parámetros de forma sencilla. Las operaciones que necesitan un tipo array se pueden componer tanto pasando el array de parámetros como añadiendo una o varias etapas del mismo. El orden es indiferente, lo único a tener en cuenta es el origen "from" y el destino "exec/execute". Por ejemplo:

vm.from(vm.datasource.identification).filter(getDataStatusFilters()).group(vm.getGroupFields()).select(vm.getSelectFields()).sort(vm.getSortFields()).exec();

Las "chaining operations" permitidas son las siguientes: from, where (filter), offset (skip), limit(max), group, project(select), sort, param, debug, exec (execute)

Un ejemplo con un datasource restaurants, del tipo :

vm.from("restaurants")
	.project([{"field":"Restaurant.cuisine","alias":"cui"},{"field":"Restaurant.cuisine","alias":"coun","op":"count"}])
	.group("Restaurant.cuisine") //o se puede poner varios como ["Restaurant.cuisine","Restaurant.borough"] 
    .exec()
    .then(
		function(data){
			vm.data = data;
		});

y en el html puedes poner el {{vm.data}} para ver el resultado de la consulta.