Поиск…


Вступление

В приложении SuitesScript 2.0 предусмотрены 4 метода обработки результатов поиска.

Они имеют различный синтаксис, ограничения и управление и подходят для разных ситуаций. Мы сосредоточимся здесь о том , как получить доступ ко всем результатам поиска, используя каждый из этих методов.

Использование метода Search.ResultSet.each

Это самый короткий, самый простой и наиболее часто используемый метод. К сожалению, он имеет одно основное ограничение - не может использоваться для поиска с более чем 4000 результатами (строками).

    // Assume that 'N/search' module is included as 'search'
    
    var s = search.create({
        type : search.Type.TRANSACTION,
        columns : ['entity','amount'],
        filters : [  ['mainline', 'is', 'T'],
              'and', ['type', 'is', 'CustInvc'],
              'and', ['status', 'is', 'open']
            ]
    });

    var resultSet = s.run();
    
    // you can use "each" method on searches with up to 4000 results    
    resultSet.each( function(result) {
        
        // you have the result row. use it like this....
        var transId = result.id;
        var entityId = result.getValue('entity'); 
        var entityName = result.getText('entity');
        var amount = result.getValue('amount');
        
        // don't forget to return true, in order to continue the loop
        return true;  

    });

Использование метода ResultSet.getRange

Чтобы использовать getRange для обработки большого количества результатов, нам нужно будет рассмотреть следующее:

  1. getRange имеет 2 параметра: начало и конец . Всегда положительный, всегда (начало <конец)
  2. start - это инклюзивный индекс первого результата для возврата
  3. end - это эксклюзивный индекс последнего результата для возврата
  4. Если доступно меньше результатов, чем запрошено, тогда массив будет содержать меньше, чем начальные записи. Например, если есть только 25 результатов поиска, getRange (20, 30) вернет массив из 5 объектов search.Result.
  5. Хотя приведенное выше предложение поддержки не говорит об этом напрямую, начало и конец могут быть вне диапазона доступных результатов. В том же примере - если есть только 25 результатов поиска, getRange (100, 200) вернет пустой массив []
  6. Максимум 1000 строк за раз. (конец - старт) <= 1000
    // Assume that 'N/search' module is included as 'search'
    
    // this search will return a lot of results (not having any filters) 
    var s = search.create({
        type: search.Type.TRANSACTION,
        columns : ['entity','amount'],
        filters: [] 
    });
    
    var resultSet = s.run();

    // now take the first portion of data.
    var currentRange = resultSet.getRange({
            start : 0,
            end : 1000
    });
    
    var i = 0;  // iterator for all search results
    var j = 0;  // iterator for current result range 0..999

    while ( j < currentRange.length ) {
        
        // take the result row
        var result = currentRange[j];
        // and use it like this....
        var transId = result.id;
        var entityId = result.getValue('entity'); 
        var entityName = result.getText('entity');
        var amount = result.getValue('amount');
        
        // finally:
        i++; j++;
        if( j==1000 ) {   // check if it reaches 1000
            j=0;          // reset j an reload the next portion
            currentRange = resultSet.getRange({
                start : i,
                end : i+1000
            });
        }
    }

Позволяет рассчитать управление. У нас есть 1 + счет / 1000 вызовов getRange, каждый из которых составляет 10 единиц, поэтому:

G = (1 + счет / 1000) * 10

Пример: 9500 строк будут принимать 100 единиц

Использование метода Search.PagedData.fetch

PagedData - это объект, возвращаемый методом Search.runPaged (options). Он работает точно так же, как и пользовательский интерфейс. Объект PagedData содержит 2 важных свойства, которые вы можете увидеть в правой части заголовка результатов на странице результатов поиска в пользовательском интерфейсе Netsuite:

  • count (общее количество результатов)
  • pageRanges (список страниц, доступных в пользовательском интерфейсе как селектор со списком)

Параметр options.pageSize снова ограничен 1000 строками результата.
Метод PagedData.fetch используется для извлечения нужной части результата (индексируется параметром pageIndex). С немного больше кода вы получаете ту же удобную функцию обратного вызова, что и Search.ResultSet.each, без ограничения на 4000 строк.

    // Assume that 'N/search' module is included as 'search'

    // this search will return a lot of results (not having any filters)  
    var s = search.create({
        type: search.Type.TRANSACTION,
        columns : ['entity','amount'],
        filters : [] 
    });
    
    var pagedData = s.runPaged({pa​g​e​S​i​z​e : 1000});
    
    // iterate the pages
    for( var i=0; i < pagedData.pageRanges.length; i++ ) {

        // fetch the current page data
        var currentPage = pagedData.fetch(i);

        // and forEach() thru all results
        currentPage.data.forEach( function(result) {

            // you have the result row. use it like this....
            var transId = result.id;
            var entityId = result.getValue('entity'); 
            var entityName = result.getText('entity');
            var amount = result.getValue('amount');

        });

    }

Позволяет рассчитать управление. У нас есть 5 единиц для вызовов runPaged () и 1 + count / 1000 pagedData.fetch, каждый из которых занимает 5 единиц, поэтому:

G = 5 + ceil (количество / 1000) * 5

Пример: 9500 строк занимают 55 единиц. Примерно половина единиц управления getRange.

Использование специального сценария Map / Reduce

Для действительно огромных результатов поиска вы можете использовать выделенный сценарий Map / Reduce. Это гораздо более неудобно, но иногда неизбежно. И иногда это может быть очень удобно.
Хитрость здесь заключается в том, что на этапе ввода входных данных вы можете предоставить NS-движку не фактические данные (т. Е. Результат скрипта), а просто определение поиска. NS выполнит поиск для вас без учета единиц управления. Затем каждая строка результата будет передана на этап Map.
Конечно, существует ограничение: общий сохраненный размер данных для сценария map / reduce не может превышать 50 МБ. В результате поиска каждый ключ и сериализованный размер каждого значения подсчитываются по отношению к общему размеру. «Сериализованный» означает, что строка результата поиска преобразуется в строку с помощью JSON.stringify. Таким образом, размер значения пропорционален количеству столбцов результатов поиска в наборе результатов. Если вы столкнулись с проблемами с ошибкой STORAGE_SIZE_EXCEEDED, подумайте об уменьшении столбцов, объединении с формулами, группировании результата или даже разбиении поиска на несколько подпоследований, которые могут быть выполнены на этапах Map или Reduce.

    /**
     * @NApiVersion 2.0
     * @NScriptType MapReduceScript
     */
    define(['N/search'], function(search) {

    function getInputData()
    {
        return search.create({
            type: search.Type.TRANSACTION,
            columns : ['entity','amount'],
            filters : [] 
        });
    }

    function map(context)
    {
        var searchResult = JSON.parse(context.value);
        // you have the result row. use it like this....
        var transId = searchResult.id;
        var entityId = searchResult.values.entity.value;
        var entityName = searchResult.values.entity.text;
        var amount = searchResult.values.amount.value;
        
        // if you want to pass some part of the search result to the next stage
        // write it to context:
        context.write(entityId, transId);
    }

    function reduce(context)
    {
       // your code here ...
    }

    function summarize(summary)
    {
        // your code here ...
    }

    return {
        getInputData: getInputData,
        map: map,
        reduce: reduce,
        summarize: summarize
    };
});

Конечно, пример здесь упрощен, без обработки ошибок и дается просто для сравнения с другими. Дополнительные примеры доступны в примерах Map / Reduce Script Type в справочном центре NS



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow