netsuite
Ricerche con un numero elevato di risultati
Ricerca…
introduzione
Suitescript 2.0 fornisce 4 metodi per gestire i risultati della ricerca.
Hanno sintassi, limitazioni e governance differenti e sono appropriati per situazioni diverse. Ci concentreremo qui su come accedere a TUTTI i risultati di ricerca, utilizzando ciascuno di questi metodi.
Utilizzando il metodo Search.ResultSet.each
Questo è il metodo più breve, più semplice e più comunemente usato. Sfortunatamente, ha una limitazione importante - non può essere utilizzato nelle ricerche con più di 4000 risultati (righe).
// 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;
});
Utilizzo del metodo ResultSet.getRange
Per utilizzare getRange per gestire il gran numero di risultati, dovremo considerare quanto segue:
- getRange ha 2 parametri: inizio e fine . Sempre positivo, sempre (inizio <fine)
- start è l'indice inclusivo del primo risultato da restituire
- fine è l'indice esclusivo dell'ultimo risultato da restituire
- Se sono disponibili meno risultati di quelli richiesti, la matrice conterrà meno voci di fine avvio. Ad esempio, se ci sono solo 25 risultati di ricerca, getRange (20, 30) restituirà un array di 5 oggetti search.Result.
- Sebbene la precedente frase di aiuto non lo dica direttamente, sia l' inizio che la fine potrebbero essere al di fuori dell'intervallo dei risultati disponibili. Nello stesso esempio: se ci sono solo 25 risultati di ricerca, getRange (100, 200) restituirà un array vuoto []
- Massimo 1000 righe alla volta. (fine - inizio) <= 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
});
}
}
Calcoliamo la Governance. Abbiamo 1 + count / 1000 chiamate getRange che richiedono 10 unità ciascuna, quindi:
G = (1 + count / 1000) * 10
Esempio: 9500 righe richiedono 100 unità
Utilizzando il metodo Search.PagedData.fetch
PagedData è un oggetto, restituito dal metodo Search.runPaged (opzioni). Funziona esattamente come fanno le ricerche dell'interfaccia utente. L'oggetto PagedData contiene 2 proprietà importanti, che è possibile vedere sul lato destro dell'intestazione dei risultati nella pagina dei risultati di ricerca nell'interfaccia utente di Netsuite:
- conteggio (il numero totale dei risultati)
- pageRanges (elenco di pagine, disponibile nell'interfaccia utente come selettore di caselle combinate)
Il parametro options.pageSize è limitato di nuovo a 1000 righe di risultati.
Il metodo PagedData.fetch viene utilizzato per recuperare la porzione di risultati desiderata (indicizzata dal parametro pageIndex). Con un po 'più di codice, si riceve la stessa comoda funzione di callback di Search.ResultSet.each, senza la limitazione di 4000 righe.
// 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');
});
}
Calcoliamo la Governance. Abbiamo 5 unità per runPaged () e 1 + count / 1000 pagedData.fetch chiamate che prendono 5 unità ciascuna, quindi:
G = 5 + ceil (count / 1000) * 5
Esempio: 9500 righe prenderanno 55 unità. Circa la metà delle unità di governance getRange.
Usando lo script dedicato Mappa / Riduci
Per risultati di ricerca davvero enormi, puoi utilizzare lo script dedicato Mappa / Riduci. È molto più sconveniente, ma a volte inevitabile. E a volte potrebbe essere molto utile.
Il trucco qui è che, nella fase Get Input Data, è possibile fornire al motore NS non i dati effettivi (cioè il risultato dello script), ma solo la definizione della ricerca. NS eseguirà la ricerca senza contare le unità di governance. Quindi ogni singola riga di risultato verrà passata alla fase Mappa.
Naturalmente, c'è una limitazione: la dimensione totale persistente dei dati per uno script mappa / riduzione non può superare i 50 MB. In un risultato di ricerca, ogni chiave e la dimensione serializzata di ciascun valore viene contata rispetto alla dimensione totale. "Serializzato" significa che la riga del risultato della ricerca viene convertita in stringa con JSON.stringify. Pertanto, la dimensione del valore è proporzionale al numero di colonne dei risultati di ricerca in un set di risultati. Se riscontri problemi con l'errore STORAGE_SIZE_EXCEEDED, prendi in considerazione la possibilità di ridurre le colonne, combinare formule, raggruppare il risultato o anche dividere la ricerca in più ricerche secondarie, che potrebbero essere eseguite in modalità Mappa o Riduci fasi.
/**
* @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
};
});
Ovviamente l'esempio qui è semplificato, senza errori di gestione e viene dato solo per essere confrontato con gli altri. Ulteriori esempi sono disponibili in Map / Reduce Script Type esempi nel NS Help Center