Actually I have done client side pagination using datatables but now requirement has changed due to large number of records around 100K.
I need to implement server side pagination.
For that I used below code
GSP
$('#data-grid-table').dataTable( {
"processing" : true,
"sAjaxSource": dataUrl,
"serverSide" : true,
"sPaginationType": "full",
"iDisplayLength": 25,
"aLengthMenu": [[25, 50, 100, -1], [25, 50, 100, "All"]],
"scrollX": true,
"bFilter": false,
"columnDefs": [ {
searchable: false,
"orderable": false,
className: "view-cell",
targets: 0
}],
"aaSorting": [[1,'asc']],
"fnDrawCallback": function( oSettings ) {
var callBackFlag = $("#hidden-view-flag").val()
if(callBackFlag=="1"){
$("#hidden-view-flag").val("2")
}
if(callBackFlag == "2"){
$("#hidden-view-flag").val("3")
}
if(hideViewColumn){
$(".view-cell").hide();
}
$('.datasetTable, tbody').find('tr').each(function(){
$(this).find('th:nth-child(1)').removeClass("sorting_asc");
});
}
});
Controller
dbObjArray = new BasicDBObject[2]
dbObjArray[0]= cruxLevel
dbObjArray[1] = project
List<DBObject> pipeline = Arrays.asList(dbObjArray)
if (!datasetObject?.isFlat && jsonFor != 'collection-grid') {
output= dataSetCollection.aggregate(pipeline)
}else{
//def skipRecords = params.iDisplayStart
//def limitRecords = params.iDisplayLength
//println 'params.iDisplayStart' + params.iDisplayStart
//println 'params.iDisplayLength' + params.iDisplayLength
println 'else-====================='
DBObject limit = new BasicDBObject('$limit':10);
DBObject skip = new BasicDBObject('$skip':5);
isFlatOutput = true;
dbObjArray = new BasicDBObject[3]
dbObjArray[0]= project
dbObjArray[1]= skip
dbObjArray[2]= limit
List<DBObject> pipeline1 = Arrays.asList(dbObjArray)
AggregationOptions aggregationOptions = AggregationOptions.builder()
.batchSize(100)
.outputMode(AggregationOptions.OutputMode.CURSOR)
.allowDiskUse(true)
.build();
SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
Date now = new Date();
println 'Start time to fetch -------------------------------------' + sdfDate.format(now)
output = dataSetCollection.aggregate(pipeline1,aggregationOptions)
Date now1 = new Date();
println 'End time to fetch-------------------------------' + sdfDate.format(now1)
}
if(isFlatOutput){
SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
Date now2 = new Date();
println 'Start time to retrieve-------------------------------' + sdfDate.format(now2)
while(output.hasNext()) {
dataList.add(output.next());
}
Date now3 = new Date();
println 'End time to retrieve-------------------------------' + sdfDate.format(now3)
}
I was not getting how to take limit and skip so I have hard coded it.
Actual result: 10 results are displaying but next is disabled.
Expected result : 10 results should display and fetch next 10 records on click of next button.
Kindly tell me where I am going wrong.
def skipRecords
def limitRecords
if(params.iDisplayStart == null){
skipRecords = 0;
}
if(params.iDisplayLength == null){
limitRecords = 25;
}
def dbObjArrayTotal = new BasicDBObject[1]
dbObjArrayTotal[0]= project
List<DBObject> pipelineTotal = Arrays.asList(dbObjArrayTotal)
AggregationOptions aggregationOptions = AggregationOptions.builder()
.batchSize(100)
.outputMode(AggregationOptions.OutputMode.CURSOR)
.allowDiskUse(true)
.build();
def totalCount = dataSetCollection.aggregate(pipelineTotal,aggregationOptions)
totalCount = totalCount.size()
if(limitRecords == -1){
limitRecords = totalCount
}
DBObject limit = new BasicDBObject('$limit':limitRecords);
DBObject skip = new BasicDBObject('$skip':skipRecords);
dbObjArray = new BasicDBObject[3] dbObjArray[0]= project
dbObjArray[1]= skip
dbObjArray[2]= limit
List<DBObject> flatPipeline = Arrays.asList(dbObjArray)
output = dataSetCollection.aggregate(flatPipeline,aggregationOptions)
def serverData = [
"iTotalRecords" : totalCount,
"iTotalDisplayRecords" : totalCount,
"aaData": yourResult]
return serverData;
And above GSP is correct use as it is.
Related
I trying the following query in spring onto the template, that query works in Mongoserver, but when I using the query in the SpringMongo template, the filter does not work, it gets all date, instead of filters date. If anyone knows this issue. pls, help me out this.
The Native Mongo Query:-
db.Task_Status.aggregate([{
{"$addFields":{"timeDiff": { $floor: { $divide: [ { $subtract:[ new Date() , "$currenttime" ] } , 60000 ] } } }},
{$match:{$and:[{"timeDiff":{"$lt": 12}}]}} }]);
The Spring MongoTempalte java Code:
String nativeFilterQuery = "{\"$addFields\":{\"timeDiff\": { $floor: { $divide: [ { $subtract:[ new Date() , \"$currenttime\" ] } , 60000 ] } } }},{$match:{$and:[{\"timeDiff\":{\"$lt\": 12}}]}}";
List<TaskStatus> amTaskLists = Collections.EMPTY_LIST;
List<AggregationOperation> aggregationOperations = new ArrayList<>();
if (StringUtility.isNotNullOrEmpty(nativeFilterQuery)) {
aggregationOperations.add(new CustomProjectAggregationOperation(nativeFilterQuery));
}
TypedAggregation<TaskStatus> aggregation = Aggregation.newAggregation(TaskStatus.class, aggregationOperations);
AggregationResults result = execute(aggregation, TaskStatus.class);
amTaskLists = result.getMappedResults();
When I split the query and Run like following its works
String queryOne = "{\"$addFields\":{\"timeDiff\": { $floor: { $divide: [ { $subtract:[ new Date() , \"$currenttime\" ] } , 60000 ] } } }}";
String queryTwo = "{$match:{$and:[{\"timeDiff\":{\"$lt\": 12}}]}}";
List<AggregationOperation> aggregationOperations = new ArrayList<>();
if (StringUtility.isNotNullOrEmpty(queryOne)) {
aggregationOperations.add(new CustomProjectAggregationOperation(queryOne));
}
if (StringUtility.isNotNullOrEmpty(queryTwo)) {
aggregationOperations.add(new CustomProjectAggregationOperation(queryTwo));
}
You can use AggregationOperation for performing different aggregation in springmongo,but $addFields not support till 3.2 version for that use DBObject for creating query.
For example i used addFields to add score in textcriria my AggregationOperation is:
AggregationOperation score = new AggregationOperation() {
#Override
public DBObject toDBObject(AggregationOperationContext aggregationOperationContext) {
return new BasicDBObject(
"$addFields",
new BasicDBObject("score", new BasicDBObject("$meta","textScore"))
);
}
};
So you can use in your way to find timeDiff and also create match function and you can use like:
List<AggregationOperation> dataListopeartion = new ArrayList<>();
MatchOperation match = new MatchOperation(new Criteria().andOperator(Criteria.where("timeDiff").lte(12));
dataListopeartion.add(match);
dataListopeartion.add(score); //your timeDiff query with AggregationOperation
Aggregation agg = Aggregation.newAggregation(dataListopeartion);
AggregationResults<TaskStatus> groupResults = mongoTemplate.aggregate(agg, Task_Status,TaskStatus.class);
ListMongoWrapper<TaskStatus> mongoWrapper = groupResults.getMappedResults();
You can also refer following answer of SO for better understanding:
link1, link2
I am new to Java and to Google Script Editor. I have a custom CRM spreadsheet in google sheets, and would like to set up reminder emails based on regularly scheduled follow-up dates. I'm having trouble with the code. I think the trouble may be due to the fact that I'm trying to compare a date to a string, but I can't figure out how to get it to work.
The goal is to send off an email when the date for follow-up matches today's date. The date for follow-up is calculated based on a formula.
Even when the log reads:
[16-07-28 13:38:06:549 PDT] Date is Thu Jul 28 2016 00:00:00 GMT-0700 (PDT)
[16-07-28 13:38:06:549 PDT] Today is Thu Jul 28 2016 00:00:00 GMT-0700 (PDT)
My If statement if (date == todayFull) doesn't work. Here's the code:
function sendEmails() {
var ss = SpreadsheetApp.openById("number");
var sheet = ss.getSheetByName("Script");
var startRow = 2; // First row of data to process
var lastRow = sheet.getLastRow();
var lastCol = sheet.getLastColumn();
// Fetch the range of cells
var dataRange = sheet.getRange(2, 1, lastRow, lastCol);
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (var i = 0; i < data.length; ++i) {
var row = data[i];
var date = row[32];
var todayFull = new Date();
todayFull.setHours(0);
todayFull.setMinutes(0);
todayFull.setSeconds(0);
Logger.log("Date is "+date);
Logger.log("Today is "+todayFull);
if (date == todayFull) {
Logger.log("This is a test. The Date is Today");
// var emailAddress = row[28]; // Email column
// var groupName = row[3]; // Group Name column
// var subject = "Follow up with this group right now!";
// MailApp.sendEmail(emailAddress, subject, groupName);
};
};
}
Thanks for the help. The first answer ended up working most of the way. Using .getDate() helped, but I also had to add arguments for month and year. Here's the code I ended up with:
function sendEmails() {
var ss = SpreadsheetApp.openById("");
var sheet = ss.getSheetByName("");
var startRow = 4; // First row of data to process
var lastRow = sheet.getLastRow(); //Get the last row of data to be processed
var lastCol = sheet.getLastColumn();
var dataRange = sheet.getRange(2, 1, lastRow-3, lastCol);
var data = dataRange.getValues();
for (var i = 0; i < data.length; ++i) {
var row = data[i];
var date2 = new Date(row[24]); // creates a new Date (date in string) object
var todayFull2 = new Date(); // creates a new Date (now) object
if (date2.getDate() == todayFull2.getDate() && date2.getMonth() == todayFull2.getMonth() && date2.getYear() == todayFull2.getYear()) {
etc
You're comparing two different data types:
var date = row[32]; // reads in a String object
var todayFull = new Date(); // creates a new Date (now) object
...
if (date == todayFull) { // compares Date with String
...
}
You might be better off creating the Date object when you read the value from your Sheet, and then comparing the actual dates in milliseconds (at time 00:00:00:00 of given date) of those Date objects, as you appear to be intending to do:
var date = new Date(row[32]); // creates a new Date (date in string) object
var todayFull = new Date(); // creates a new Date (now) object
todayFull.setHours(0,0,0,0) // sets time to midnight of current day
...
// compare Date with Date
if (date.getTime() == todayFull.getTime()) {
...
}
See MDN's excellent documentation on Javascript's Date.
I am attempting to get the items and some of the related information from a Purchase Order with SuiteTalk. I am able to get the desired Purchase Orders with TransactionSearch using the following in Scala:
val transactionSearch = new TransactionSearch
val search = new TransactionSearchBasic
...
search.setLastModifiedDate(searchLastModified) //Gets POs modified in the last 10 minutes
transactionSearch.setBasic(search)
val result = port.search(transactionSearch)
I am able to cast each result to a record as an instance of the PurchaseOrder class.
if (result.getStatus().isIsSuccess()) {
println("Transactions: " + result.getTotalRecords)
for (i <- 0 until result.getTotalRecords) {
try {
val record = result.getRecordList.getRecord.get(i).asInstanceOf[PurchaseOrder]
record.get<...>
}
catch {...}
}
}
From here I am able to use the getters to access the individual fields, except for the ItemList.
I can see in the NetSuite web interface that there are items attached to the Purchase Orders. However using getItemList on the result record is always returning a null response.
Any thoughts?
I think you have not used search preferences and that is why you are not able to fetch purchase order line items. You will have to use following search preferences in your code -
SearchPreferences prefrence = new SearchPreferences();
prefrence.bodyFieldsOnly = false;
_service.searchPreferences = prefrence;
Following is working example using above preferences -
private void SearchPurchaseOrderByID(string strPurchaseOrderId)
{
TransactionSearch tranSearch = new TransactionSearch();
TransactionSearchBasic tranSearchBasic = new TransactionSearchBasic();
RecordRef poRef = new RecordRef();
poRef.internalId = strPurchaseOrderId;
poRef.type = RecordType.purchaseOrder;
poRef.typeSpecified = true;
RecordRef[] poRefs = new RecordRef[1];
poRefs[0] = poRef;
SearchMultiSelectField poID = new SearchMultiSelectField();
poID.searchValue = poRefs;
poID.#operator = SearchMultiSelectFieldOperator.anyOf;
poID.operatorSpecified = true;
tranSearchBasic.internalId = poID;
tranSearch.basic = tranSearchBasic;
InitService();
SearchResult results = _service.search(tranSearch);
if (results.status.isSuccess && results.status.isSuccessSpecified)
{
Record[] poRecords = results.recordList;
PurchaseOrder purchaseOrder = (PurchaseOrder)poRecords[0];
PurchaseOrderItemList poItemList = purchaseOrder.itemList;
PurchaseOrderItem[] poItems = poItemList.item;
if (poItems != null && poItems.Length > 0)
{
for (var i = 0; i < poItems.Length; i++)
{
Console.WriteLine("Item Line On PO = " + poItems[i].line);
Console.WriteLine("Item Quantity = " + poItems[i].quantity);
Console.WriteLine("Item Descrition = " + poItems[i].description);
}
}
}
}
I am using aggregate() method and looking result in cursor for that I am using below code
dbObjArray = new BasicDBObject[2]
dbObjArray[0]= cruxLevel
dbObjArray[1] = project
// dbObjArray[2] = out
List<DBObject> pipeline = Arrays.asList(dbObjArray)
if (!datasetObject?.isFlat && jsonFor != 'collection-grid') {
println '-------------------------------- inside if block bbb--------------------------------------'
output= dataSetCollection.aggregate(pipeline)
}else{
/*DBObject out = new BasicDBObject('$out':"datasetTemp");
def db = getDB()*/
println '-------------------------------- inside else block--------------------------------------'
AggregationOptions aggregationOptions = AggregationOptions.builder()
.batchSize(100)
.outputMode(AggregationOptions.OutputMode.CURSOR)
.allowDiskUse(true)
.build();
output = dataSetCollection.aggregate(project)
}
I am getting below error.
com.mongodb.CommandFailureException: { "serverUsed" :
"127.0.0.1:15847" , "errmsg" : "exception: pipeline element 0 is not
an object" , "code" : 15942 , "ok" : 0.0}
Where I'm going wrong please help!
Thank you.
def dbObjArray = new BasicDBObject[1]
dbObjArray[0]= project
List<DBObject> flatPipeline = Arrays.asList(dbObjArray)
AggregationOptions aggregationOptions = AggregationOptions.builder()
.batchSize(100)
.outputMode(AggregationOptions.OutputMode.CURSOR)
.allowDiskUse(true)
.build();
def cursor = dataSetCollection.aggregate(flatPipeline,aggregationOptions)
I am using Jquery Datatable with server side processing in order to process all my data. My parameter '2' is a date, which I enter in as a String, convert to a Date to add to the database, however, use a String again to display to the webpage. This works fine for 'GetData' process. However, when I enter in a new dataset using 'AddData', I get the error in the title. It seems that only the two columns that deal with Date are throwing this error, the rest of the row gets written. As soon as I refresh the page, everything does back to normal.
This is my datatable script:
var i = 0;
$(document).ready(function(){
oTable = $("#datatables").dataTable({
"aoColumns" : [
{ "sName" : attendingPhysician" },
{ "sName" : "physicianName" },
{ "sName" : "dateStart" },
{ "sName" : "dateEnd" },
{ "sName" : "teamNumber" }
],
"sAjaxSource" : 'teamassignmentdata',
"sServerMethod": "GET",
"fnDrawCallback" : function(oSettings) {
//The call to makeEditable is set here to make sure all the data are loaded
i++;
if(i == 1) {
this.makeEditable({
sUpdateURL : 'UpdateTeamAssignmentData',
sAddNewRowFormId: "formAddNewRow",
sAddNewRowButtonId: "btnAddNewRow",
sAddNewRowOkButtonId: "btnAddNewRowOk",
sAddNewRowCancelButtonId: "btnAddNewRowCancel",
sAddURL: "AddTeamAssignmentData",
sAddHttpMethod: "POST",
aoColumns : [
{}, //physician number; default editing
{}, //physician name; default editing
{ //date start; datepicker
type : 'datepicker',
datepicker : {
dateFormat : 'yy-mm-dd'
}
},
{
type : 'datepicker',
datepicker : {
dateFormat : 'yy-mm-dd'
}
}, //date end; datepicker
{ //team number; no editing
indicator: 'Saving...',
tooltip: 'Click to edit team number',
loadtext: 'loading...',
type: 'select',
onblur: 'submit',
data: "{'5':'5','6':'6','7':'7','8':'8','9':'9'}"
}
],
height : "20px"
});
}
}
});
});
And this is the method that is actually entering the data into the database, and outputting it to the datatable.
String physician = request.getParameter("physician");
String physicianname = request.getParameter("physicianname");
String datestart = request.getParameter("datestart");
String dateend = request.getParameter("dateend");
String team = request.getParameter("team");
boolean addSuccess = true;
PhysicianTeamData physicianTeamData = new PhysicianTeamData();
String sql = "INSERT INTO " + TABLE_NAME + " " +
"(team_attendingPhysician, team_physicianName, team_dateStart, " +
"team_dateEnd, team_teamNumber) VALUES (?,?,?,?,?);";
int returnId = 0;
try {
dateStart = dateFormat.parse(datestart);
dateEnd = dateFormat.parse(dateend);
sqlDateStart = new java.sql.Date(dateStart.getTime());
sqlDateEnd = new java.sql.Date(dateEnd.getTime());
ps = con.prepareStatement(sql);
ps.setInt(1, Integer.parseInt(physician));
ps.setString(2, physicianname);
ps.setDate(3, sqlDateStart);
ps.setDate(4, sqlDateEnd);
ps.setString(5, team);
returnId = ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
addSuccess = false;
}
PrintWriter out = response.getWriter();
if(addSuccess) {
PhysicianTeam pt = new PhysicianTeam();
pt.setRecordNumber(returnId);
pt.setAttendingPhysician(Integer.parseInt(physician));
pt.setPhysicianName(physicianname);
pt.setDateStart(datestart.toString());
pt.setdateEnd(dateend.toString());
pt.setTeamNumber(Integer.parseInt(team));
physicianTeamData.addPhysicianTeamData(pt);
//out.print(returnId);
out.print(pt);
} else {
out.write("Row Add Failed!");
}
PhysicianTeamData is just an arraylist, and these are the fields in PhysicianTeam class:
private int attendingPhysician;
private String physicianName;
private String dateStart;
private String dateEnd;
private int teamNumber;
Like I mentioned, the JSON object puts dateStart as parameter '2' and dateEnd as parameter '3', both of which are throwing error, even though I am outputting them as a String.
Where am I going wrong?