9 Introduction to Searching with SuiteScript 2.0
Created: June 26, 2017
In this edition, we start looking at how to transition our Searches from SuiteScript 1.0 over to 2.0. This is quite an important and lengthy concept in SuiteScript, so we'll be exploring Searching over several weeks.
To coincide with this series of articles on Searching, I have also created a series of SuiteScript cookbooks focused on Searching. These cookbooks are intended to provide you with reference examples for the most common Searching concepts and techniques.
N/search Module
In SuiteScript 1.0, there were two separate APIs for performing Searches. The first was the nlapiSearchRecord method that would create the Search, execute the Search, and return the results all in one call. The second API broke the creation, execution, and results retrieval into separate method calls.
In SuiteScript 2.0, all searching capabilities are provided by the N/search
module. The N/search
module API mimics that of the latter API from 1.0.
There is no direct 2.0 equivalent for nlapiSearchRecord
.
In SuiteScript 2.0, you will be creating or loading the Search, executing the Search, and retrieving the results all with separate method calls.
Loading and Executing a Search
To start, let's investigate an example of loading and executing a Saved Search. We'll start with a very simple Saved Search that shows all Employees hired in the current year.
// 1.0
var search = nlapiLoadSearch("employee", "customsearch_emp_hiredthisyear");
var resultSet = search.runSearch();
// 2.0 - Console
require(["N/search"], function (s) {
var search = s.load({id: "customsearch_emp_hiredthisyear"});
var resultSet = search.run();
});
In 1.0, we leverage nlapiLoadSearch
to obtain a reference to the Saved Search,
then we call its runSearch
method to execute the Search on the server.
The 2.0 version of this same functionality looks very similar. We begin by
calling the Search module's load
method, then calling the run
method on the
Search reference to execute it on the server.
Notice also that we're not declaring any specific Script module with
the define
function; instead, we're using the require
function so that you
can paste this code directly into your browser console or the NetSuite debugger
environment.
Iterating through Results
From here, in 1.0, there were two different ways we could retrieve our results
for processing. The first was by using the forEachResult
iterator method.
// 1.0
var search = nlapiLoadSearch("employee", "customsearch_emp_hiredthisyear");
var resultSet = search.runSearch();
resultSet.forEachResult(printEmployeeName);
function printEmployeeName(result) {
nlapiLogExecution("DEBUG", "Employee Name:", result.getValue("firstname"));
return true;
}
// 2.0 - Console
require(["N/search"], function (s) {
var search = s.load({id: "customsearch_emp_hiredthisyear"});
var resultSet = search.run();
resultSet.each(printEmployeeName);
function printEmployeeName(result) {
log.debug({title: "Employee Name:", details: result.getValue({name: "firstname"})});
return true;
}
});
2.0 offers an equivalent to the forEachResult
iterator: the each
iterator.
Just as in 1.0, the 2.0 each
iterator will run through at most 4000 results;
your callback function must return a Boolean value:
true
to continue iterating;false
to stop
If you're using each
, and you can't figure out why your Script is only
processing one result, please check that your callback method is returning the
appropiate boolean value. I have seen this question over and over; don't say I
didn't warn you!
The getRange Iterator
Our other option in 1.0 was the getResults
method that would retrieve a very
specific chunk of the result set.
// 1.0
var search = nlapiLoadSearch("employee", "customsearch_emp_hiredthisyear");
var resultSet = search.runSearch();
var results = resultSet.getResults(0, 1000);
for (var i = 0; i < results.length; i++) {
printEmployeeName(results[i]);
}
function printEmployeeName(result) {
nlapiLogExecution("DEBUG", "Employee Name:", result.getValue("firstname"));
}
// 2.0 - Console
require(["N/search"], function (s) {
var search = s.load({id: "customsearch_emp_hiredthisyear"});
var resultSet = search.run();
var results = resultSet.getRange({start: 0, end: 1000});
for (var i = 0; i < results.length; i++) {
printEmployeeName(results[i]);
}
function printEmployeeName(result) {
log.debug({title: "Employee Name:", details: result.getValue({name: "firstname"})});
}
});
Once again, 2.0 offers a corresponding method called getRange
. We
provide getRange
with the starting and ending index of the results we want to
retrieve. The slice
of results
can be from any part of the entire set, but
is limited to a maximum of 1000 results per call to getRange
.
Method Chaining
Now I've been fairly explicit with our method calls here, assigning each one to a variable output; however, as with most 2.0 APIs, we can chain our Search API calls to make our code a bit more concise:
require(["N/search"], function (s) {
s.load({
id: "customsearch_emp_hiredthisyear"
}).run().each(printEmployeeName);
function printEmployeeName(result) {
log.debug({
title: "Employee Name:",
details: result.getValue({name: "firstname"})
});
return true;
}
});
We can chain all of our calls to load
, run
, and each
together; we could
also chain getRange
in exactly the same way.
We have barely scratched the surface of Searches in SuiteScript 2.0; if you're looking to accelerate your mastery of searching in SuiteScript, make sure you check out the SuiteScript Cookbooks.