Step - 1 -------- Create a portal report which consists of following columns: (You may call it as 'All Tasks Grouped' report) 1. Year - year(tp!starttime) and perform group operation on it 2. Month - month(tp!starttime) and perform group operation on it 3. Day - day(tp!starttime) and perform group operation on it 4. Count (Provide any other variable or task property as default value and perform count operation on it) Step - 2 -------- Create basic bins where each bin is in the form of {year:,month:,day:,count:} and this represents the rows in the grouped report created in Step - 1 Name: createBins_Example Inputs: 1. year (Number Integer) 2. month (Number Integer) 3. day (Number Integer) 4. count (Number Integer) Definition: = { year: ri!year, month: ri!month, day: ri!day, count: ri!count } Step - 3 -------- Create a rule which creates bins by amalgamating the bins created in Step - 2. While amalgamation, this step takes care in such a way that the new bin's size doesn't exceed 10000. The aim of this step is to group bins, and also to restrict the size to 10000. The advantage of this step is, queryProcessAnalytics will be applied iteratively over these bins, so having less number of bins where each bin gives maximum capacity (of not more than 10000) Name: createAmalgamatedBins_Example Inputs: 1. data (Any type) /*This input will be your accumulated array*/ 2. bin (Any type) /*One of the records from the data obtained after querying the report created in Step 1*/ Description: This rule creates new bin (if the current bin's capacity exceeds 10000) or modifies existing bin (If the bin can still accommodate and the size is less than 10000) depending on the count of the input 'bin'. The concept of the bins is to reduce the number of analytics queries we make. Definition: =with( local!lastIndex: length(ri!data), local!lastBin: ri!data[local!lastIndex], local!lastBinSize: tointeger(local!lastBin.binsize), local!lastBinYear:tointeger(local!lastBin.years), local!lastBinMonth:tointeger(local!lastBin.months), local!thisRowSize: tointeger(ri!bin.count), local!thisRowYear:tointeger(ri!bin.year), local!thisRowMonth:tointeger(ri!bin.month), if ( or( local!lastBinSize > 10000, local!lastBinSize+local!thisRowSize > 10000, if(rule!APN_isBlank(local!lastBinYear),fn!false(),local!thisRowYear<>local!lastBinYear), if(rule!APN_isBlank(local!lastBinMonth),fn!false(),local!thisRowMonth<>local!lastBinMonth)), append(ri!data, {binsize: local!thisRowSize, months: {ri!bin.month},years: {ri!bin.year},days:{ri!bin.day}}), updatearray(ri!data, local!lastIndex, { binsize: local!lastBinSize + local!thisRowSize, months: append(local!lastBin.months, ri!bin.month), years: append(local!lastBin.years, ri!bin.year), days: append(local!lastBin.days, ri!bin.day)} ) ) ) /* The output of this rule looks like follows: { {binsize:9269,months:1; 1; 1; 1,years:2015; 2015; 2015; 2015,days:29; 13; 25; 1}, {binsize:9176,months:1; 1; 1; 1; 1; 1,years:2015; 2015; 2015; 2015; 2015; 2015,days:10; 7; 21; 6; 4; 22}, {binsize:8825,months:1; 1; 1; 1; 1; 1; 1,years:2015; 2015; 2015; 2015; 2015; 2015; 2015,days:16; 5; 15; 14; 11; 9; 17}, {binsize:8771,months:1; 1; 1; 1; 1,years:2015; 2015; 2015; 2015; 2015,days:12; 23; 2; 30; 20} } */ Step - 4 -------- Create a portal report which consists of following columns: (You may call it as 'All Tasks' report) 1. Year - year(tp!starttime) 2. Month - month(tp!starttime) 3. Day - day(tp!starttime) 4. id (tp!id) and the columns desired by you such as tp!assignees etc Step - 5 -------- Create a query analytics rule which queries the report created in Step - 3 based on the given bins and keeps on adding the data subset to datasubset which is a accumulator array Name: queryProcessAnalyticsForBin_Example Inputs: 1. resultantDataSet (Any Type) 2. bin (Any type) 3. report (Document) 4. additionalFilters (Any Type) Definition: =with( local!defaultFilterSet:{ a!queryFilter(field: "c5", operator: "in", value: ri!bin.years), a!queryFilter(field: "c6", operator: "in", value: ri!bin.months), a!queryFilter(field: "c7", operator: "in", value: ri!bin.days) /*where c5, c6, c7 corresponds to the respective columns in portal report created in Step - 4*/ }, local!filterSet:if(rule!APN_isEmpty(ri!additionalFilters),local!defaultFilterSet,append(local!defaultFilterSet,ri!additionalFilters)), local!reportData:a!queryProcessAnalytics( report:ri!report, query: a!query( logicalExpression: a!queryLogicalExpression( operator: "AND", filters: local!filterSet ), pagingInfo: a!pagingInfo( startIndex: 1, batchSize: -1 ) ) ), if(local!reportData.totalCount=0,ri!resultantDataSet,if(rule!APN_isEmpty(ri!resultantDataSet),local!reportData.data,append(ri!resultantDataSet,local!reportData.data))) ) Step - 6 -------- Create the main rule which accepts the basic inputs such as reports and filters and return the dataset at any cost irrespective of its size. Name: queryProcessAnalytics_Example Description: This expression retrieves the entire dataset from a given portal report by opting for the grouping, bins approach in case of maximum rows (greater than 10000) and in the normal way when the rows are less than 10000. Inputs: 1. report (Document) 2. groupedReport (Document) 3. filterSet (Any Type) Definition: with( /*Get the total count*/local!totalCount: a!queryProcessAnalytics( report:ri!report, query: a!query( logicalExpression: if(rule!APN_isEmpty(ri!filterSet),null,a!queryLogicalExpression( operator: "AND", filters: ri!filterSet )), pagingInfo: a!pagingInfo( startIndex: 1, batchSize: 1 ) ) ).totalCount, if( local!totalCount = 0, null, if( local!totalCount <= 10000, with( /*Results within execution engine limits*/a!queryProcessAnalytics( report:ri!report, query: a!query( pagingInfo: a!pagingInfo( startIndex: 1, batchSize: -1 ) ) ).data ), with( /*Results NOT within execution engine limits*/ local!groupedProcessDataPortalReportDataSubset: a!queryProcessAnalytics( report:ri!groupedReport, query: a!query( pagingInfo: a!pagingInfo( startIndex: 1, batchSize: -1 ) ) ), local!bins:apply( rule!createBins_Example( year: _, month: _, day:_, count: _ ), merge( index(local!groupedProcessDataPortalReportDataSubset.data,"c5",null),/*corresponds to year column in grouped report created in Step - 1*/ index(local!groupedProcessDataPortalReportDataSubset.data,"c6",null),/*corresponds to month column in grouped report created in Step - 2*/ index(local!groupedProcessDataPortalReportDataSubset.data,"c7",null),/*corresponds to date column in grouped report created in Step - 3*/ index(local!groupedProcessDataPortalReportDataSubset.data,"c0",null)/*corresponds to count column in grouped report created in Step - 4*/ ) ), local!amalgamatedBins:reduce(rule!createAmalgamatedBins_Example,{{binsize:0,months:{},years:{},days:{}}}, local!bins), reduce(rule!queryProcessAnalyticsForBin_Example,{},local!amalgamatedBins,{ri!report},ri!filterSet) ) ) ) ) Implementation in your interface: --------------------------------- load( local!pagingInfo: a!pagingInfo( startIndex: 1, batchSize: 50, sort: a!sortInfo( field: "c3", ascending: false ) ), local!statusFilter: null, local!button, local!process, local!task, local!assigned, local!accept, local!columnConfigs: a!queryProcessAnalytics( report: cons!ALL_TASK_REPORT, query: a!query( pagingInfo: a!pagingInfo( startIndex: 1, batchSize: 1 ) ) ).columnConfigs, local!additionalFilters: null, local!allTasksReportData:: rule!queryProcessAnalytics_Example(report:cons!ALL_TASK_REPORT,groupedReport: < PLACE GROUPED REPORT CONSTANT HERE>,filterSet:local!additionalFilters), with( local!datasubset: todatasubset( local!allTasksReportData, local!pagingInfo ), a!dashboardLayout( firstColumnContents: { a!sectionLayout( firstColumnContents: { a!dropdownField( label: "Status", choiceLabels: { "Assigned", "Accepted", "Completed" }, choiceValues: enumerate( 3 ), placeholderLabel: "All", value: local!statusFilter, saveInto: { local!statusFilter, a!save( local!pagingInfo.startIndex, 1 ) } ), a!textField( label: "Search By Task Display Name", value: local!task, refreshAfter: "KEYPRESS", saveInto: { local!task, a!save( local!pagingInfo.startIndex, 1 ) } ) }, secondColumnContents: { a!pickerFieldUsersAndGroups( label: "Filter by Assigned To", value: local!accept, maxSelections: 1, saveInto: { local!accept, a!save( local!pagingInfo.startIndex, 1 ) } ), a!pickerFieldUsers( label: "Accepted By", value: local!assigned, maxSelections: 1, saveInto: { local!assigned, a!save( local!assigned, tostring( save!value ) ), a!save( local!pagingInfo.startIndex, 1 ) } ), a!buttonLayout( primaryButtons: { a!buttonWidget( label: "Submit", style: "PRIMARY", value: "Submit", saveInto: { local!button, a!save( local!additionalFilters, if( and( isnull( local!statusFilter ), isnull( local!task ), isnull( local!assigned ), or( isnull( local!accept ), local!accept = "" ) ), null, { if( isnull( local!statusFilter ), null, a!queryFilter( field: "c1", operator: "=", value: local!statusFilter ) ), if( isnull( local!task ), null, a!queryFilter( field: "c6", operator: "includes", value: local!task ) ), if( or( isnull( local!accept ), local!accept = "" ), null, a!queryFilter( field: "c4", operator: "in", value: local!accept ) ), if( isnull( local!assigned ), null, a!queryFilter( field: "c5", operator: "=", value: local!assigned ) ) } ) ), a!save( local!allTasksReportData, rule!queryProcessAnalytics_Example(report:cons!ALL_TASK_REPORT,groupedReport: < PLACE GROUPED REPORT CONSTANT HERE>,filterSet:local!additionalFilters) ) } ) } ) } ), if(or(isnull(local!datasubset),local!datasubset=""), {}, a!sectionLayout( firstColumnContents: { a!gridField( label: "All Task Report", totalCount: local!datasubset.totalCount, columns: { apply( rule!util_portalReportColumn(columnConfig: _, data: local!datasubset.data), local!columnConfigs ) }, value: local!pagingInfo, saveInto: local!pagingInfo ) })) } ) ) )