netsuite
Búsquedas con gran cantidad de resultados.
Buscar..
Introducción
Suitescript 2.0 proporciona 4 métodos para manejar los resultados de búsqueda.
Tienen diferentes sintaxis, limitaciones y gobernanza, y son apropiados para diferentes situaciones. Nos centraremos aquí en cómo acceder a TODOS los resultados de búsqueda, utilizando cada uno de estos métodos.
Usando el método Search.ResultSet.each
Este es el método más corto, fácil y usado. Desafortunadamente, tiene una limitación importante: no se puede utilizar en búsquedas con más de 4000 resultados (filas).
// 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;
});
Usando el método ResultSet.getRange
Para utilizar getRange para manejar la gran cantidad de resultados, tendremos que considerar lo siguiente:
- getRange tiene 2 parámetros: inicio y final . Siempre positivo, siempre (inicio <fin)
- Inicio es el índice inclusivo del primer resultado a devolver.
- End es el índice exclusivo del último resultado a devolver.
- Si hay menos resultados disponibles que los solicitados, entonces la matriz contendrá menos de las entradas de inicio final. Por ejemplo, si solo hay 25 resultados de búsqueda, entonces getRange (20, 30) devolverá una matriz de 5 objetos search.Result.
- Aunque la oración de ayuda anterior no lo dice directamente, tanto el inicio como el final podrían estar fuera del rango de resultados disponibles. En el mismo ejemplo, si solo hay 25 resultados de búsqueda, getRange (100, 200) devolverá una matriz vacía []
- Máximo 1000 filas a la vez. (final - inicio) <= 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
});
}
}
Permite calcular la gobernanza. Tenemos 1 + recuento / 1000 llamadas getRange que toman 10 unidades cada una, así que:
G = (1 + cuenta / 1000) * 10
Ejemplo: 9500 filas tomarán 100 unidades.
Usando el método Search.PagedData.fetch
PagedData es un objeto, devuelto por el método Search.runPaged (opciones). Funciona exactamente como lo hacen las búsquedas de interfaz de usuario. El objeto PagedData contiene 2 propiedades importantes, que puede ver en el lado derecho del encabezado de resultados en la página de resultados de búsqueda en la interfaz de usuario de Netsuite:
- contar (el número total de los resultados)
- pageRanges (lista de páginas, disponible en UI como selector de cuadro combinado)
El parámetro options.pageSize se limita de nuevo a 1000 filas de resultados.
El método PagedData.fetch se usa para obtener la parte del resultado que desea (indexado por el parámetro pageIndex). Con un poco más de código, recibirá la misma función de devolución de llamada conveniente que Search.ResultSet.each, sin tener el límite de 4000 filas.
// 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({pageSize : 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');
});
}
Permite calcular la gobernanza. Tenemos 5 unidades para las llamadas runPaged () y 1 + count / 1000 pagedData.fetch que toman 5 unidades cada una, por lo que:
G = 5 + ceil (contar / 1000) * 5
Ejemplo: 9500 filas tomarán 55 unidades. Aproximadamente la mitad de las unidades de gobierno de getRange.
Usando un mapa dedicado / Reducir script
Para resultados de búsqueda realmente grandes, puede usar un mapa dedicado / Reducir script. Es mucho más inconveniente, pero a veces inevitable. Y a veces podría ser muy útil.
El truco aquí es que, en la etapa Obtener datos de entrada, puede proporcionar al motor de NS no los datos reales (es decir, el resultado del script), sino solo la definición de la búsqueda. NS ejecutará la búsqueda por ti sin contar las unidades de gobierno. Luego, cada fila de un solo resultado se pasará a la etapa Mapa.
Por supuesto, hay una limitación: el tamaño total persistido de los datos para un script de mapa / reducción no puede exceder los 50 MB. En un resultado de búsqueda, cada clave y el tamaño serializado de cada valor se cuentan para el tamaño total. "Serializado" significa que la fila del resultado de la búsqueda se convierte en cadena con JSON.stringify. Por lo tanto, el tamaño del valor es proporcional al número de columnas de resultados de búsqueda en un conjunto de resultados. Si llega a tener problemas con el error STORAGE_SIZE_EXCEEDED, considere la posibilidad de reducir las columnas, combinarlas en fórmulas, agrupar el resultado o incluso dividir la búsqueda en varias búsquedas secundarias, que podrían ejecutarse en las etapas Mapa o Reducir.
/**
* @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
};
});
Por supuesto, el ejemplo aquí es simplificado, sin manejo de errores y se da solo para compararlo con otros. Hay más ejemplos disponibles en Map / Reduce Script Type en el Centro de ayuda de NS