Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Suitescript 2.0 ResultSet.Each Callback Function Exceeded 4000

I wrote a script (below) a couple years ago (haven't been coding since - so there is a fair amount or rust ;D) where the ResultSet now exceeds 4000 records which was not anticipated when the script was written. The error is below:

{"type":"error.SuiteScriptError","name":"SSS_SEARCH_FOR_EACH_LIMIT_EXCEEDED","message":"No more than 4000 search results may be returned at one time from nlobjSearchResultSet.forEachResult(callback). Please revise your search criteria or modify the callback logic so that no more than 4000 results are returned."...

Is the best way to fix this to use a different technique (like Map/Reduce - which I'd have to learn now), or is there a way to filter the search so only a certain number of results are returned from the search and the rest of the records get returned/processed in a subsequent execution?

Thanks

//...
invoiceSearch.run().each(function(result) {
    // ensure script usage okay
    if (usageOkay()) {
        entityID = result.getValue({
            'name': 'internalid',
            'join': 'customer',
            'summary': search.Summary.GROUP
        });

        var maxAmountCustomerRecord = result.getValue({
            'name': 'custentity_amount_maxorder_2years',
            'join': 'customer',
            'summary': search.Summary.GROUP
        });

        var maxAmountCalculated = result.getValue({
            'name': 'formulacurrency',
            'formula': 'CASE WHEN {closedate} >= ADD_MONTHS(SYSDATE, -(12 * 2)) THEN {amount} ELSE NULL END',
            'summary': search.Summary.MAX
        });
        // in case the calculated amount is null then make it 0
        maxAmountCalculated = maxAmountCalculated || 0.0;
        // Only write to the customer record when a change is required
        if (maxAmountCustomerRecord != maxAmountCalculated) {
            updateRecord(entityID, maxAmountCalculated);
            log.debug('Updating customer with entityID: ' + entityID + ', to maxAmount: ' +
                maxAmountCalculated + ', from previous value of ' + maxAmountCustomerRecord);
        }
        return true;
    }
    else {
        // If remaining script usage low, reschedule script
        rescheduleScript(entityID);
    }
});
//....
like image 402
Rob G Avatar asked Jan 28 '26 15:01

Rob G


1 Answers

I personally like to generate the full search, then parse it from there:

I use this function with any search object to compile the results in blocks of 1000:

function getAllResults(s) {
    var results = s.run();
    var searchResults = [];
    var searchid = 0;
    do {
        var resultslice = results.getRange({start:searchid,end:searchid+1000});
        resultslice.forEach(function(slice) {
            searchResults.push(slice);
            searchid++;
            }
        );
    } while (resultslice.length >=1000);
    return searchResults;
}   

Then when I want to process any search, for example:

var mySearch = search.create({
                type:'invoice',
                columns: [
                    {name: 'tranid'},
                    {name: 'trandate'},
                    {name: 'entity', sort: (params.consolidated)?search.Sort.ASC:undefined },
                    {name: 'parent',join:'customer', sort: (!params.consolidated)?search.Sort.ASC:undefined},
                    {name: 'terms'},
                    {name: 'currency'},
                    {name: 'amount'},
                    {name: 'amountremaining'},
                    {name: 'fxamount'},
                    {name: 'fxamountremaining'},
                ],
                filters: [
                    {name: 'mainline', operator:'is',values:['T']},
                    {name: 'trandate', operator:'onorbefore', values: [params.startDate] }
                ]
            });

var myResults = getAllResults(mySearch );

myResults.forEach(function(result) {

//... do stuff with each result

});

I've used this with good results on data sets in excess of 20,000 records.

like image 106
Steve Reeder Avatar answered Jan 30 '26 03:01

Steve Reeder



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!