Suitescript 2.0 ResultSet.Each Callback Function превышает 4000

Я написал сценарий (ниже) пару лет назад (с тех пор не занимался кодированием - так что есть изрядное количество или ржавчина; D), где ResultSet теперь превышает 4000 записей, чего не ожидалось, когда сценарий был написан. Ошибка ниже:

{"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."...

Наилучший способ исправить это - использовать другую технику (например, Map / Reduce - которую я должен был бы изучить сейчас), или есть способ отфильтровать поиск, чтобы из поиска возвращалось только определенное количество результатов и остальные записи возвращаются / обрабатываются при последующем выполнении?

Спасибо

//...
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);
    }
});
//....
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
0
2 018
3

Ответы 3

Моя рекомендация и, возможно, лучший способ массовой обработки в SuiteScript 2.0 - использовать Map / Reduce, а не Scheduled Script. С ними, безусловно, нужно научиться, но они чрезвычайно эффективны.

Быстрые подсказки будут:

  1. Ваша точка входа getInputData может просто создать / загрузить все, что есть invoiceSearch в существующем скрипте, и вернуть его.
  2. Вы сможете избавиться от всего мониторинга использования, так как вам не нужно делать это самостоятельно с помощью M / R
  3. Ваша точка входа reduce будет фактически внутренностями вашего утверждения if.

Надеюсь, это должно быть довольно простое преобразование.

Хотя Эрик отвечает так, как я бы, наверное, пошел, иногда нужно делать запланированный сценарий. И, конечно же, в этом случае, если вы думаете, что проработаете все элементы за день запланированных запусков, то простое решение:

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

});

Я использовал это с хорошими результатами для наборов данных, превышающих 20 000 записей.

Другие вопросы по теме