Saiku嵌入系统使用时传参数访问saiku

Saiku通过iframe嵌入其他系统使用时,我们可以设定参数信息,然后根据url中参数对结果进行筛选哦。

这里我们实现的是根据日期字段进行范围查询,URL请求中需要多加如下两个参数  startdate , enddate ,也就是开始日期与结束日期。

实现日期的范围查询 saiku  date range,主要有以下步骤

1. 修改源代码 saiku-ui 项目下的 js\saiku\models\Query.js(如果你不是本地编译的源码也可以直接修改 saiku-server\tomcat\webapps\ROOT\js\saiku\models 目录下的 Query.js )

在Query.js下的 run方法中增加如下代码段:

//根據用戶輸入的開始日期與結束日期查詢範圍數據
var dimensionArr = exModel.queryModel.axes.ROWS.hierarchies; //取出行信息中的所有维度信息 dimension,用一个数组接收
  for(var i=0;i<dimensionArr.length;i++){
//判断维度信息中是否有countdate这个时间维度(这是固定的)
if(dimensionArr[i]!=null && dimensionArr[i].dimension == "countdate" ){
var paramsURI = Saiku.URLParams.paramsURI(); //得到URl中传过来的参数信息
//判断参数是否为空
if(paramsURI.startdate != null && paramsURI.startdate != undefined && paramsURI.startdate != ""&&
paramsURI.enddate != null && paramsURI.enddate != undefined && paramsURI.enddate != ""){
var startdate=paramsURI.startdate; //获取开始日期
var enddate=paramsURI.enddate; //获取结束日期
//更改level下的mdx表达式,将日期范围的筛选信息添加到mdx表达式中
dimensionArr[i].levels.countdate.mdx="[countdate].[countdate].[countdate].["+startdate+"]:[countdate].[countdate].[countdate].["+enddate+"]"; }
}
}

这里最主要的是就是找到需要改动的位置了:(文末提供了修改后完整的Query.js文件)

exModel.queryModel.axes.ROWS.hierarchies 这个数组中找到countdate ,然后再修改countdate对应 levels.coundate下的mdx值

层级关系如下图:(0是可变的哟,可能是下标1,2,3..... 所以上面代码中用到了 for循环去找 countdate )

2. saiku中xml文件中的cube中必须配置日期字段,我用的是countdate字段,配置如下

   <Dimension name="countdate" foreignKey="ID" >
<Hierarchy hasAll="true" primaryKey="ID" allMemberName="countdate" >
<Level name="countdate" table="aaa" column="countdate" type='Date' uniqueMembers="false" /> <!--这里的 column=countdate ,countdate为数据库的表中的日期字段名,可根据自己的表灵活变动啦-->
</Hierarchy>
</Dimension>

 

3.Saiku配置数据信息的时候需要将日期字段拖到  行 数据框

4.使用url发请求访问saiku中需带入startdate,enddate参数 (如果不带入这两个参数的话就不会进行范围筛选啦!!!然后就会正常查询全量数据)

模板URL如下:

  http://10.99.77.78:8080/?username=admin&password=aaa&startdate=2019-03-06%2000:00:00.0&enddate=2019-03-10%2000:00:00.0&plugin=false&mode=view#query/open//KPI/aa.saiku

URL解析

  http://10.99.77.78:8080/    #是我的saiku的访问地址

  username=admin&password=aaa   #分别是我登录saiku的用户名以及密码

  startdate=2019-03-06%2000:00:00.0&enddate=2019-03-10%2000:00:00.0    #是我设定的开始时间以及结束时间,我想查询countdate值为3.6到3.10的数据。这里需要说明一下我的countdate中有2019-03-06 00:00:00.0 ,2019-03-10 00:00:00.0  这两个值哦。

  plugin=false&mode=view#query/open/    #这里指不以插件的方式嵌入,嵌入的模式为view(会带出导出excel那一排工具栏信息)

  /KPI/aa.saiku   #这个就是我保存的数据信息啦,我自己新建了个KPI目录,然后保存的数据命名为 aa .

5.过滤结果如下图:

解析:( 其实上面添加的注释已经比较详细的,嘻嘻  ,需要注意的主要有以下4点)

1. 数据库中必须有一个countdate日期字段(名字当然可以随意)

2.Schema文件中 对应的cube信息中必须配置 countdate字段如下:(关键的是  Dimension下的name  Hierarchy下的allMemerName  Level下的name 命名都为countdate )

    <Dimension name="countdate" foreignKey="ID" >
<Hierarchy hasAll="true" primaryKey="ID" allMemberName="countdate" >
<Level name="countdate" table="aaa" column="countdate" type='Date' uniqueMembers="false" /> <!--这里的 column=countdate ,countdate为数据库的表中的日期字段名,可根据自己的表更改-->
</Hierarchy>
</Dimension>

3.如果需要根据日期进行范围筛选,url中必须添加参数 startdate,enddate 哦

4.想要获取正确的筛选结果,startdate以及enddate的值必须是当前cube中已有的值!!!(不然就会报错啦,就像你在saiku中使用参数一样,参数值一定要填写当前结果中已有的值,关于日期就很较真啦,时分秒都要对应上才行哦)  

>>>更改后的Query.js文件

这里再提供一下修改之后的完整Query.js ,其它地方都没有改动,就只是添加了上方内容,详情如下

Query.js

/*
* Copyright 2012 OSBI Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ /**
* Workspace query
*/
var Query = Backbone.Model.extend({ formatter: Settings.CELLSET_FORMATTER,
properties: null, initialize: function(args, options) {
// Save cube
_.extend(this, options); // Bind `this`
_.bindAll(this, "run"); // Generate a unique query id
this.uuid = 'xxxxxxxx-xxxx-xxxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,
function (c) {
var r = Math.random() * 16 | 0,
v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
}).toUpperCase(); this.model = _.extend({ name: this.uuid }, SaikuOlapQueryTemplate);
if (args.cube) {
this.model.cube = args.cube;
}
this.helper = new SaikuOlapQueryHelper(this); // Initialize properties, action handler, and result handler
this.action = new QueryAction({}, { query: this });
this.result = new Result({ limit: Settings.RESULT_LIMIT }, { query: this });
this.scenario = new QueryScenario({}, { query: this }); // A flag to tell who changed selection members
this.updatedSelectionFromModal = false;
}, parse: function(response) {
// Assign id so Backbone knows to PUT instead of POST
this.id = this.uuid;
if (response.name) {
this.id = response.name;
this.uuid = response.name;
}
this.model = _.extend(this.model, response);
this.model.properties = _.extend({}, Settings.QUERY_PROPERTIES, this.model.properties);
}, setProperty: function(key, value) {
this.model.properties[key] = value;
}, getProperty: function(key) {
return this.model.properties[key];
}, syncSelectionsModalAndUpdateParameters: function() {
if (this.updatedSelectionFromModal) {
var mParameters = this.helper.model().parameters;
for (var mKey in mParameters) {
var mVal = mParameters[mKey];
var selections = this.helper.getSelectionsForParameter(mKey); mVal = selections.map(function(sel) { return sel.caption; }).join();
mParameters[mKey] = mVal;
}
} else {
var mParameters = this.helper.model().parameters;
for (var mKey in mParameters) {
var mVal = mParameters[mKey];
var mLevel = this.helper.getLevelForParameter(mKey);
var selections = this.helper.getSelectionsForParameter(mKey); if (mVal !== null && mVal !== undefined) {
this.helper.setSelectionsForParameter(mKey, _.filter(selections, function(sel) {
var containsParam = false;
_.each(mVal.split(','), function (v) {
if (sel.caption === v) {
containsParam = true;
return false;
}
});
return containsParam;
}));
}
}
} this.updatedSelectionFromModal = false;
}, run: function(force, mdx) {
this.syncSelectionsModalAndUpdateParameters(); var self = this;
// Check for automatic execution
Saiku.ui.unblock();
if (typeof this.model.properties != "undefined" && this.model.properties['saiku.olap.query.automatic_execution'] === false &&
(force === false || force === undefined || force === null)) {
return;
}
this.workspace.unblock(); $(this.workspace.el).find(".workspace_results_info").empty();
this.workspace.trigger('query:run');
this.result.result = null;
var validated = false;
var errorMessage = '<span class="i18n">Query Validation failed!</span>'; var exModel = this.helper.model();
for(var k in this.attributes) {
var att = this.attributes[k];
if(k.substring(0,5)==="PARAM"){
var p = k.substring(5, k.length);
exModel.parameters[p] = att;
} }
if (exModel.queryType == "OLAP") {
if (exModel.type == "QUERYMODEL") {
var columnsOk = Object.keys(exModel.queryModel.axes.COLUMNS.hierarchies).length > 0;
var rowsOk = Object.keys(exModel.queryModel.axes.ROWS.hierarchies).length > 0;
var detailsOk = exModel.queryModel.details.axis == 'COLUMNS' && exModel.queryModel.details.measures.length > 0;
if (!rowsOk || !columnsOk || !detailsOk) {
errorMessage = "";
}
if (!columnsOk && !detailsOk) {
errorMessage += '<span class="i18n">You need to include at least one measure or a level on columns for a valid query.</span>';
}
if(!rowsOk) {
errorMessage += '<span class="i18n">You need to include at least one level on rows for a valid query.</span>'; }
if ( (columnsOk || detailsOk) && rowsOk) {
validated = true;
} } else if (exModel.type == "MDX") {
validated = (exModel.mdx && exModel.mdx.length > 0);
if (!validated) {
errorMessage = '<span class="i18n">You need to enter some MDX statement to execute.</span>';
}
}
}
if (!validated) {
this.workspace.table.clearOut();
$(this.workspace.processing).html(errorMessage).show();
this.workspace.adjust();
Saiku.i18n.translate();
return;
} // Run it
this.workspace.table.clearOut();
$(this.workspace.processing).html('<span class="processing_image">  </span> <span class="i18n">Running query...</span> [ <a class="cancel i18n" href="#cancel">Cancel</a> ]').show();
this.workspace.adjust();
this.workspace.trigger('query:fetch');
Saiku.i18n.translate();
var message = '<span class="processing_image">  </span> <span class="i18n">Running query...</span> [ <a class="cancel i18n" href="#cancel">Cancel</a> ]';
this.workspace.block(message);
/*
TODO: i wonder if we should clean up the model (name and captions etc.)
delete this.model.queryModel.axes['FILTER'].name;
*/ //根據用戶輸入的開始日期與結束日期查詢範圍數據
var dimensionArr = exModel.queryModel.axes.ROWS.hierarchies; //取出行信息中的所有维度信息 dimension,用一个数组接收
for(var i=0;i<dimensionArr.length;i++){
//判断维度信息中是否有countdate这个时间维度(这是固定的)
if(dimensionArr[i]!=null && dimensionArr[i].dimension == "countdate" ){
var paramsURI = Saiku.URLParams.paramsURI(); //get the param from url
//判断参数是否为空
if(paramsURI.startdate != null && paramsURI.startdate != undefined && paramsURI.startdate != ""&&
paramsURI.enddate != null && paramsURI.enddate != undefined && paramsURI.enddate != ""){
var startdate=paramsURI.startdate;
var enddate=paramsURI.enddate;
//更改level下的mdx表达式
dimensionArr[i].levels.countdate.mdx="[countdate].[countdate].[countdate].["+startdate+"]:[countdate].[countdate].[countdate].["+enddate+"]"; }
}
} this.result.save({},{ contentType: "application/json", data: JSON.stringify(exModel), error: function() {
Saiku.ui.unblock();
var errorMessage = '<span class="i18n">Error executing query. Please check the server logs or contact your administrator!</span>';
self.workspace.table.clearOut();
$(self.workspace.processing).html(errorMessage).show();
self.workspace.adjust();
Saiku.i18n.translate();
} });
}, enrich: function() {
var self = this;
this.workspace.query.action.post("/../enrich", {
contentType: "application/json",
data: JSON.stringify(self.model),
async: false,
success: function(response, model) {
self.model = model;
}
});
}, url: function() {
return "api/query/" + encodeURI(this.uuid);
}
});

 

Saiku嵌入系统使用时传参数访问saiku(十六)的更多相关文章

  1. SSH hibernate 使用时最好添加访问数据库的编码

    SSH hibernate 使用时最好添加访问数据库的编码 如下所示:第13行为设置hibernate访问数据库的编码(&是&的转义序列) <!DOCTYPE hibernate ...

  2. 分页传参数的两种形式,url正则 ?id=1

    目的: 打开http://127.0.0.1:8000/home    点击查看详情转到 http://127.0.0.1:8000/detail-1-1.html实现查看具体信息 一,利用url路由 ...

  3. Saiku多用户使用时数据同步刷新(十七)

    Saiku多用户使用时数据同步刷新 这里我们需要了解一下关于saiku的刷新主要有两种数据需要刷新: >1 刷新数据库的表中的数据,得到最新的表数据进行展示. >2 刷新cube信息,得到 ...

  4. 【WPF】当 ItemsSource 正在使用时操作无效。改用 ItemsControl.ItemsSource 访问和修改元素

    问题: 中文版报错:Additional information: 当 ItemsSource 正在使用时操作无效.改用 ItemsControl.ItemsSource 访问和修改元素. 英文版报错 ...

  5. linux系统使用sh文件传参数给matlab程序

      linux系统下使用sh文件传参数给matlab程序 (1)编写sh文件 程序以下面的行开始(必须在文件的第一行):   #!/bin/sh 定义需要传递的参数,用双引号引起,参数之间使用逗号或分 ...

  6. ASP.NET MVC WebApi 返回数据类型序列化控制(json,xml) 用javascript在客户端删除某一个cookie键值对 input点击链接另一个页面,各种操作。 C# 往线程里传参数的方法总结 TCP/IP 协议 用C#+Selenium+ChromeDriver 生成我的咕咚跑步路线地图 (转)值得学习百度开源70+项目

    ASP.NET MVC WebApi 返回数据类型序列化控制(json,xml)   我们都知道在使用WebApi的时候Controller会自动将Action的返回值自动进行各种序列化处理(序列化为 ...

  7. Windows系统下的TCP参数优化(注册表\TCPIP\Parameters)

    转自:https://blog.csdn.net/libaineu2004/article/details/49054261 Windows系统下的TCP参数优化   TCP连接的状态与关闭方式及其对 ...

  8. python 全栈开发,Day120(路由系统, 实例化Flask的参数, 蓝图(BluePrint), before_request after_request)

    昨日内容回顾 1.Flask: from flask import Flask app = Flask(__name__) # 从源码中可以看出,Flask集成的run方法是由werkzeug中的ru ...

  9. C#多线程函数如何传参数和返回值

          详见网站:http://WWW.MOVIH.COM就是一个多线程爬虫系统.   C#多线程函数如何传参数和返回值 提起多线程,不得不提起 委托(delegates)这个概念. 我理解的委托 ...

随机推荐

  1. python全栈开发day118-Mui

    1.什么是Mui Mui是前端布局框架 封装了HTML5PLUS HTML5PLUS是移动操作系统的调用接口 2.Mui代码块,用于快速构建Mui组件 1).打开一个窗口 Mui.openWindow ...

  2. RESTful-5开发API

    RESTful 是目前最流行的 API 设计规范,用于 Web 数据接口的设计. 它的大原则容易把握,但是细节不容易做对.本文总结 RESTful 的设计细节,介绍如何设计出易于理解和使用的 API. ...

  3. 在WINDOWS中安装使用SIGPACK(MinGW64+Sublime Text3 &Visual Studio)

    本文介绍在Windows下安装使用SigPack库,涉及Armadillo.OpenBLAS安装使用说明,最终实现对SigPack示例CPP基于MinGW64在Sublime Text3下的编译运行, ...

  4. 自我介绍&软工实践博客点评

    想想既然写了点评博客,那就顺便向同学们介绍下自己吧. 我是16届计科实验班的,水了两件小黄衫,于是就来当助教了_(:_」∠)_ 实话说身为同届生来当助教,我心里还是有点虚的,而且我还是计科的..感觉软 ...

  5. 手机QQ公众号亿级消息实时群发架构

    编者按:高可用架构分享及传播在架构领域具有典型意义的文章,本文由孙子荀分享.转载请注明来自高可用架构公众号 ArchNotes.   孙子荀,2009 年在华为从事内核和分布式系统的开发工作:2011 ...

  6. 展开被 SpringBoot 玩的日子 《 一 》入门篇

    SpringBoot 已经是久闻大名了,因各种原因导致迟迟未展开学习SpringBoot,今天,我将会逐渐展开被SpringBoot 玩的历程,有兴趣的,可以跟我一起来~~~~~~~ 什么是sprin ...

  7. Linux网络文件系统的实现与调试

    NFS协议 NFS (网络文件系统)不是传统意义上的文件系统,而是访问远程文件系统的网络协议.整个NFS服务的TCP/IP协议栈如下图所示,NFS是应用层协议,表示层是XDR,会话层是RPC,传输层同 ...

  8. [python]numpy.mean()用法

    a=np.array([[[1,1],[2,2],[3,3]],[[4,4],[5,5],[6,6]],[[7,7],[8,8],[9,9]],[[10,10],[11,11],[12,12]]]) ...

  9. nginx配置前端代理

    #user nobody;worker_processes 1; #error_log logs/error.log;#error_log logs/error.log notice;#error_l ...

  10. vue调用 Highcharts 实现多个数据可视化展示

    一创建一个 options.js 代码为: export const option1 = { bar: { title: { text: '珠海猪场' // 指定图表标题 }, credits: { ...