Javascript Suitescript 2.0结果集。每个回调函数超过4000个

Javascript Suitescript 2.0结果集。每个回调函数超过4000个,javascript,callback,netsuite,suitescript,suitescript2.0,Javascript,Callback,Netsuite,Suitescript,Suitescript2.0,我在几年前写了一个脚本(如下)(从那时起就没有编码过——因此有相当数量的结果集超过了4000条记录,这是编写脚本时没有预料到的。错误如下: {“type”:“error.SuiteScriptError”,“name”:“SSS_SEARCH_FOR_every_LIMIT_extended”,“message”:“从nlobjSearchResultSet.forEachResult(回调)一次返回的搜索结果不能超过4000个。请修改搜索条件或修改回调逻辑,使返回的结果不超过4000个。” 解

我在几年前写了一个脚本(如下)(从那时起就没有编码过——因此有相当数量的结果集超过了4000条记录,这是编写脚本时没有预料到的。错误如下:

{“type”:“error.SuiteScriptError”,“name”:“SSS_SEARCH_FOR_every_LIMIT_extended”,“message”:“从nlobjSearchResultSet.forEachResult(回调)一次返回的搜索结果不能超过4000个。请修改搜索条件或修改回调逻辑,使返回的结果不超过4000个。”

解决这一问题的最佳方法是使用不同的技术(如Map/Reduce,我现在必须学习),还是有一种方法可以过滤搜索,以便只从搜索中返回一定数量的结果,并在后续执行中返回/处理其余记录

谢谢

/。。。
invoiceSearch.run().each(函数(结果){
//确保脚本使用正常
if(usageOkay()){
entityID=result.getValue({
'name':'internalid',
“加入”:“客户”,
“摘要”:search.summary.GROUP
});
var maxAmountCustomerRecord=result.getValue({
“名称”:“客户实体金额最大订单年”,
“加入”:“客户”,
“摘要”:search.summary.GROUP
});
var MaxAmountComputed=result.getValue({
“名称”:“公式货币”,
'公式':'当{closedate}>=ADD_MONTHS(SYSDATE,-(12*2))然后{amount}ELSE NULL END'时的情况,
“摘要”:search.summary.MAX
});
//如果计算的金额为空,则将其设为0
MaxAmountComputed=MaxAmountComputed | | 0.0;
//仅在需要更改时写入客户记录
如果(maxAmountCustomerRecord!=maxAmountCalculated){
updateRecord(entityID,maxAmountCalculated);
log.debug('正在将entityID为“+entityID+”的客户更新为maxAmount:'+
maxAmountCalculated+,来自先前的值“+maxAmountCustomerRecord);
}
返回true;
}
否则{
//如果剩余的脚本使用率较低,请重新计划脚本
重新调度脚本(entityID);
}
});

//..
我的建议,也可能是SuiteScript 2.0中批量处理的最佳实践,是使用Map/Reduce而不是预定的脚本。它们当然有一定的学习曲线,但功能非常强大

快速提示包括:

  • 您的
    getInputData
    入口点可以创建/加载现有脚本中的
    invoiceSearch
    并返回它
  • 您将能够摆脱所有的使用监控,因为您不需要自己使用M/R进行监控
  • 你的
    reduce
    切入点实际上就是
    如果你有
    语句的话

  • 希望这应该是一个相当简单的转换。

    Eric的答案是我可能会采用的方式,有时需要执行计划脚本。当然,在这种情况下,如果您认为您可以在一天的计划运行中完成所有项目,那么简单的修复方法是:

    var count = 0;
    invoiceSearch.run().each(function(result) {
       count++;
       if(count == 4000) return false;
       if(usageOk(){
         ...
         return true;
       }else{
         rescheduleScript(entityID);
          return false; // end the each and you may never hit 4k anyway
       }
    });
    

    我个人喜欢生成完整搜索,然后从那里解析它:

    我将此函数用于任何搜索对象,以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;
    }   
    
    然后,当我要处理任何搜索时,例如:

    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
    
    });
    
    我已经在超过20000条记录的数据集上使用了它,并取得了很好的效果