Saiku部分函数解析与默认添加日期限制查詢(八)

Saiku部分函数解析与默认添加日期限制查詢

Saiku函数解析

now()  :  获取当前日期

IIF(logic_exp, string, string): IIF判断,logic_exp是逻辑表达式,结果为true/false , 为true的时候取第二个参数值,为false的时候取第三个参数值。  eg:  IIF(1>2,"1大于2","1不大于2")   ,   结果为 1不大于2

year(Date) : 获取日期的年份信息  eg: YEAR(cdate("2019-02-26"))

CDate(String) : 将String类型的数据转换为日期类型   eg: CDate("2019-02-26")

STR( numeric):  将数据类型转换为String类型 eg:  STR(55.6)

DateDiff(String, Date, Date) : 得到日期相减的值,第一个参数表示interval,第二个参数是日期类型,第三个是日期类型, eg:  datediff("y", CDate("2019-02-26"), CDate("2019-02-25"))  结算逻辑为 得出2019-02-26至 2019-02-25中相差的天数,结果为 1

interval的取值如下:

Saiku查询设定:Saiku查询数据时,每次都是全量查询的,我们现在需要默认展示近一周的数据。

实现默认查询一周数据方案一:使用MDX表达式

通过编写MDX表达式,添加新的指标信息对一周以内的数据进行标识 (其实我也想添加新的维度信息,但是好像不生效,所以就用指标了)

/** 检测日期的差值,小于7 */
IIf(DateDiff("d",CDate([SaikuUseDate].[SaikuUseDate].CurrentMember.Name), now())> 7, "yes", "no") 

/** 检测日期差值大于0并且小于7 (显示最近一周的数据) 但是其他年份的相同月份的数据也会显示出来*/
IIF(datediff("y",cdate(now()),cdate([SaikuUseDate].[SaikuUseDate].CurrentMember.Name))<=7,
IIF(datediff("y",cdate(now()),cdate([SaikuUseDate].[SaikuUseDate].CurrentMember.Name))>=0,"週數據","非週數據"),"非週數據")

//处理不同年份的日期差值问题(固定年份差值为0,表示只判定当年的数据) year(now()) 取的值为2019
IIF(datediff("y",cdate(now()),cdate([SaikuUseDate].[SaikuUseDate].CurrentMember.Name))<=7,
IIF(datediff("y",cdate(now()),cdate([SaikuUseDate].[SaikuUseDate].CurrentMember.Name))>=0,
IIF( year(cdate(now())) - year(cdate([SaikuUseDate].[SaikuUseDate].CurrentMember.Name))=0,"週數據","非週數據"),"非週數據"),"非週數據")

 其中SaikuUseDate是我自定义的日期维度信息,在schame中的定义如下:

    <Dimension name="SaikuUseDate"  foreignKey="ID" >
            <Hierarchy hasAll="true" primaryKey="ID" allMemberName="SaikuUseDate">
              <Level name="SaikuUseDate" column="saikuUseDate" type='Date'  uniqueMembers="false" />
            </Hierarchy>
        </Dimension>

  

区分最近一周数据与其他数据最终的MDX表达式语句为:

IIF(datediff("y",cdate(now()),cdate([SaikuUseDate].[SaikuUseDate].CurrentMember.Name))<=7,
  IIF(datediff("y",cdate(now()),cdate([SaikuUseDate].[SaikuUseDate].CurrentMember.Name))>=0,
    IIF( year(cdate(now())) - year(cdate([SaikuUseDate].[SaikuUseDate].CurrentMember.Name))=0,"週數據","非週數據"),
  "非週數據"),
"非週數據")

saiku中添加新的指标信息如下:

 

根据新指标信息查询结果如下:

数据已筛选好了,接下来只需要把 新指标  週數據 字段按照 週數據 與 非週數據 进行筛选就可以啦。

(目前因为saiku是社区版的,过滤不起作用所以没法演示了,后期如果解决了过滤问题会更新的)

实现默认查询一周数据方案一:更改源代码

saiku在本地进行的编译的方式前面已有教程说明,接下来就是更改原代码了 (从网上学得教程,目前只了解到获取最新一天的数据信息)

参考博客地址: https://blog.csdn.net/zstao168/article/details/52818569

1. 主要更改的类信息:在saiku-web工程中的Query2Resource.java中,具体类路径为:  /saiku-web/src/main/java/org/saiku/web/rest/resources/Query2Resource.java

在该类的 public QueryResult execute(ThinQuery tq  ) 方法中添加  tq = this.restrictQueryByDate(tq);  (execute方法大概在该类的 185-220行左右)

 /**
   *
   * Execute a Saiku Query
   * @summary Execute Query
   * @param tq Thin Query model
   * @return A query result set.
   */
    @POST
    @Consumes({"application/json" })
    @Path("/execute")
    public QueryResult execute(ThinQuery tq) {
    
    	//add code to limit query date
    	tq = this.restrictQueryByDate(tq);
        try {
            if (thinQueryService.isMdxDrillthrough(tq)) {
                Long start = (new Date()).getTime();
                ResultSet rs = thinQueryService.drillthrough(tq);
                QueryResult rsc = RestUtil.convert(rs);
                rsc.setQuery(tq);
                Long runtime = (new Date()).getTime()- start;
                rsc.setRuntime(runtime.intValue());
                return rsc;
            }

            QueryResult qr = RestUtil.convert(thinQueryService.execute(tq));
            ThinQuery tqAfter = thinQueryService.getContext(tq.getName()).getOlapQuery();
            qr.setQuery(tqAfter);
            return qr;
        }
        catch (Exception e) {
            log.error("Cannot execute query (" + tq + ")",e);
            String error = ExceptionUtils.getRootCauseMessage(e);
            return new QueryResult(error);
        }
    }

 

在Query2Resource.java类中添加 ThinQuery  restrictQueryByDate(ThinQuery tq) 方法,内容如下

  // add code for query limit
  private ThinQuery restrictQueryByDate(ThinQuery tq) {
	  
		ThinQueryModel queryModel = tq.getQueryModel();
	  	Map<AxisLocation, ThinAxis> axesMap = queryModel.getAxes();
	  	
	  	NamedList<ThinHierarchy> namedList = new NamedListImpl<ThinHierarchy>();
	  	
	  	ThinAxis filterAxis = axesMap.get(AxisLocation.FILTER);
	  	List<ThinHierarchy> filterHie = filterAxis.getHierarchies();
	  	
	  	namedList = this.resetThinHierachy(filterHie);
	  		
	  	//将修改后的Row重新set到queryModel
	  	if(namedList.size() > 0) {
	  		
			ThinAxis newFilterAxis = new ThinAxis(
					AxisLocation.FILTER,
					namedList,
					filterAxis.isNonEmpty(),
					filterAxis.getAggregators()
					);
			
			axesMap.put(AxisLocation.FILTER,newFilterAxis);
	  	}
	  	
	  	//将修改后的Row重新set到queryModel
	  	if(namedList.size() == 0) {
	  		
	  		ThinAxis rowAxis = axesMap.get(AxisLocation.ROWS);
	  	  	List<ThinHierarchy> rowHie = rowAxis.getHierarchies();
	  	  	
	  	  	namedList = this.resetThinHierachy(rowHie);
	  		
	  		if(namedList.size() > 0) {
				ThinAxis newRowsAxis = new ThinAxis(
						AxisLocation.ROWS,
						namedList,
						rowAxis.isNonEmpty(),
						rowAxis.getAggregators()
						);
				
				axesMap.put(AxisLocation.ROWS,newRowsAxis);
	  		}	
	  	}
	  	
	  	//if columns contained date member
	  	//if contained and have not set the limit ,then add limit to one day ,if do not hava then add this column and limit to one day;
	  	if(namedList.size() == 0) {
	  		
//	  		namedList.clear();
	  		
	    	ThinAxis colAxis = axesMap.get(AxisLocation.COLUMNS);
	    	List<ThinHierarchy> colHie = colAxis.getHierarchies();
	    	
	    	namedList = this.resetThinHierachy(colHie);
	    	
	    	if(namedList.size() == 0) {
	    		
	    		//if list is empty,then column don't hava date ,then add colHie to list and enfore to add date member;
	    		namedList.addAll(colHie);
	    		
	    		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
				String yesterday = format.format(new Date(new Date().getTime() - 24 * 60 * 60 * 1000));
				
				String newDateMdx = "[SaikuUseDate].[SaikuUseDate].["+yesterday+"]";
				
				ThinMember thinMember = new ThinMember(yesterday,newDateMdx,yesterday);
	    		ThinHierarchy thinHie = new ThinHierarchy();
	    		
	    		thinHie.setName("[SaikuUseDate].[SaikuUseDate]");
	    		
	    		List<ThinMember> thinMemberList = new ArrayList<ThinMember>();
				thinMemberList.add(thinMember);
				ThinSelection selection = new ThinSelection();
				selection.setMembers(thinMemberList);
				selection.setType(ThinSelection.Type.INCLUSION);
				ThinLevel thinLevel = new ThinLevel(yesterday,yesterday,selection,null);
		//  			thinLevel.setSelection(selection);
				Map<String,ThinLevel> mapLevel = new LinkedHashMap<String,ThinLevel>();
				mapLevel.put("SaikuUseDate", thinLevel);
		    		
				thinHie.setLevels(mapLevel);
				
				namedList.add(thinHie);
	    		ThinAxis newColAxis = new ThinAxis(
	    				AxisLocation.COLUMNS,
	    				namedList,
	    				colAxis.isNonEmpty(),
	    				colAxis.getAggregators()
	    				);
	    		
	    		axesMap.put(AxisLocation.COLUMNS,newColAxis);
	    	}
	  	}
	  	
	  	return tq;
	  }
	  
	  private NamedList<ThinHierarchy> resetThinHierachy(List<ThinHierarchy> hieList) {
		  
		  NamedList<ThinHierarchy> namedList = new NamedListImpl<ThinHierarchy>();
		  boolean flag = false;
		  
		  for(ThinHierarchy hie : hieList) {
		  		if(hie.getName().equals("[SaikuUseDate].[SaikuUseDate]")) {
		    		
		    		if(hie.getLevels().get("SaikuUseDate").getSelection() == null) {
		    			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		    			String yesterday = format.format(new Date(new Date().getTime() - 24 * 60 * 60 * 1000));
		    			
		    			String newDateMdx = "[SaikuUseDate].[SaikuUseDate].["+yesterday+"]";
		    			
		    			ThinMember thinMember = new ThinMember(null,newDateMdx,yesterday);
		    			
		    			List<ThinMember> thinMemberList = new ArrayList<ThinMember>();
		    			thinMemberList.add(thinMember);
		    			ThinSelection selection = new ThinSelection();
		    			selection.setMembers(thinMemberList);
		    			
		    			hie.getLevels().get("SaikuUseDate").setSelection(selection);
		    		}
		    		
		    		flag = true;
		  		}
		  		
		  		namedList.add(hie);
		  	}
		  if(flag) return namedList;
		  
		  namedList.clear();
		  return namedList;
	  
	  }
 

 

ps:  如果 hie.getLevels().get("SaikuUseDate") 中得到的ThinLevel对象没有setSeletion(selection)方法,需要手工在ThinLevel中添加set方法

还有一点需要注意,就是加上这些代码之后,saiku的schame文件中cube需要有 SaikuUseDate 日期字段

最后将整个项目打包编译即可,将新的saiku-server启动,然后配置一些数据信息,便能获取最近一天的数据信息了。

  

猜你喜欢

转载自www.cnblogs.com/DFX339/p/10439372.html