I am attempting to get the last 200 results from a paged search in SuiteScript 2.0. When I run the simple code I get the error
"name":"INVALID_PAGE_RANGE","message":"Invalid page range: fetch."
What exactly am I doing wrong?
The below code was run in the NS debugger (I have removed some code for brevity):
function(ui, email, runtime, search, file, config, format, record, log) {
var mySearch = search.load({
id: 'customsearch_mht_lrf_export_to_lab'
});
// 200 results per page (am I correct here?)
var results = mySearch.runPaged({pageSize:200});
var count = results.count; // = 264
// Obtain the last 200 results. From the documentation;
// index is 'The index of the page range that bounds the desired data.'
// Error occurs on the next line
var data = results.fetch({index: results.count});
var x = 0;
});
(I've already answered this on the Slack group, but I'll copy my answer here in case someone one day has this question and comes across the post).
The index parameter that you pass to results.fetch is the index of the "page" of data that you want. In your example above, where you have 264 results and your page size is 200, there would be 2 pages of results. Results 1 - 199 would be on the first page (index = 0), and 200 - 264 on the second page.
In order to get the last 200 results, you will always need to retrieve the last 2 pages (unless the result count is an exact multiple of 200), and then just look at the final 200 of those results.
Related
I have a large database of items that have somewhat fluid statuses. I need to get an array of those items based on what each items's status was on a given date.
Here's an excerpt from an example record:
{"status":[
{"date":{"$date":"2019-06-14T06:17:41.625Z"},"statusCode":200},
{"date":{"$date":"2019-11-04T02:02:58.020Z"},"statusCode":404},
{"date":{"$date":"2020-08-07T01:11:16.184Z"},"statusCode":200},
{"date":{"$date":"2020-08-07T03:54:09.703Z"},"statusCode":404}
]}
Using this example, the status on 2020-01-13 would be 404 (as it would be also on 2020-01-12 or any other givenDate until the status changed back to 200).
So how would I filter my big array to this record (and others like it) to only items with status 404 as of 2020-01-13? (And I would do the same for 200.)
Note that I can't simply filter for objects with date < givenDate && statusCode == 200 because that would ignore if the status changed after those records. (The above example would return for either 200 or 404 since both records exist before givenDate.)
My only idea at the moment is that I could first filter the status array to anything before givenDate, and then compare based on the last record (since this filtered array's last record would then always be before givenDate). But this seems more complicated than necessary.
Processing time isn't important to me on this because I'm trying to make some one-time corrections to past statistics.
Thanks in advance!
A bit verbose, but I think this should do what you want.
var feedHistory = {"status":[
{"date":{"$date":"2019-06-14T06:17:41.625Z"},"statusCode":200},
{"date":{"$date":"2019-11-04T02:02:58.020Z"},"statusCode":404},
{"date":{"$date":"2020-08-07T01:11:16.184Z"},"statusCode":200},
{"date":{"$date":"2020-08-07T03:54:09.703Z"},"statusCode":404}
]};
const filterByStatus = (feedHistory,statusDate) => {
let foundRecord = false;
feedHistory.forEach((record) => {
let recordDate = new Date(Date.parse(record.date['$date']));
if (recordDate < statusDate && (!foundRecord || foundRecord.parsedDate < recordDate)) {
record.parsedDate = recordDate;
foundRecord = record;
}
});
return foundRecord;
};
var statusDate = new Date('2019-06-15');
var statusOnDate = filterByStatus(feedHistory.status,statusDate);
console.log(`On ${statusDate} the status was ${statusOnDate.statusCode}`);
I am trying to hit the ends point 'https://api.foursquare.com/v2/venues/explore' with the initial parameters
{v='20180323',
near='SFO',
radius = 100000,
section='topPicks',
limit=20 }
and later on by adding offset = 20 to the above dictionary. I am expecting results from 21-40 in the second response, but I am getting the same response as my first query.
Azure Search returns a maximum of 1,000 results at a time. For paging on the client, I want the total count of matches in order to be able to display the correct number of paging buttons at the bottom and in order to be able to tell the user how many results there are. However, if there are over a thousand, how do I get the actual count? All I know is that there were at least 1,000 matches.
I need to be able to do this from within the SDK.
If you want to get total number of documents in an index, one thing you could do is set IncludeTotalResultCount to true in your search parameters. Once you do that when you execute the query, you will see the count of total documents in an index in Count property of search results.
Here's a sample code for that:
var credentials = new SearchCredentials("account-key (query or admin key)");
var indexClient = new SearchIndexClient("account-name", "index-name", credentials);
var searchParameters = new SearchParameters()
{
QueryType = QueryType.Full,
IncludeTotalResultCount = true
};
var searchResults = await indexClient.Documents.SearchAsync("*", searchParameters);
Console.WriteLine("Total documents in index (approx) = " + searchResults.Count.GetValueOrDefault());//Prints the total number of documents in the index
Please note that:
This count will be approximate.
Getting the count is an expensive operation so you should only do it with the very first request when implementing pagination.
For REST clients using the POST API, just include "count": "true" to the payload. You get the count in #odata.count.
Ref: https://learn.microsoft.com/en-us/rest/api/searchservice/search-documents
Is there a way to limit the amount of records returned via SuiteScript? I use the following method, but the search still gets all results. I am breaking out of the iteration of the results if I've hit the max I'd like to return. I can't find anything in the documentation.
In the UI it looks like one can limit the returned results, even though I haven't had much luck with it. (Maybe because I'm joining...)
var accountSearch = search.create({
type: search.Type.CUSTOMER,
columns: searchColumns,
filters: searchFilters
});
var searchResultsPagedData = accountSearch.runPaged({
'pageSize': 1000
});
var max = 9;
for (var pageIndex = 0; pageIndex < searchResultsPagedData.pageRanges.length; pageIndex++) {
var pageRange = searchResultsPagedData.pageRanges[pageIndex];
if (pageRange.index >= max)
break;
var searchPage = searchResultsPagedData.fetch({ index: pageRange.index });
// Iterate over the list of results on the current page
searchPage.data.forEach(function (result) {
}
}
Use getRange instead of each to iterate over your results. getRange lets you specify a start and end index to grab a specific slice of the results.
Why not just set the page size to the max number of results you want and only iterate over the first page (page 0)? Or if you're looking for more than 1000 results you could limit the number of pages by setting pageIndex < max; instead of pageIndex < searchResultsPagedData.pageRanges.length;
Another approach: from the comments it seems one of the issues you're having is running into the execution limit, so you could load the N/runtime module and use Script.getRemainingUsage() before each fetch to ensure you have enough governance units left - and break or return if you don't.
I have a large nlobjSearchResultSet object with over 18,000 "results".
Each result is a pricing record for a customer. There may be multiple records for a single customer.
As 18000+ records is costly in governance points to do mass changes, I'm migrating to a parent (customer) record and child records (items) so I can make changes to the item pricing as a sublist.
As part of this migration, is there a simple command to select only the nlapiSearchResult objects within the big object, which match certain criteria (ie. the customer id).
This would allow me to migrate the data with only the one search, then only subsequent create/saves of the new record format.
IN a related manner, is there a simple function call to return to number of records contained in a given netsuite record? For % progress context.
Thanks in advance.
you can actually get the number of rows by running the search with an added aggregate column. A generic way to do this for a saved search that doesn't have any aggregate columns is shown below:
var res = nlapiSearchRecord('salesorder', 'customsearch29', null,
[new nlobjSearchColumn('formulanumeric', null, 'sum').setFormula('1')]);
var rowCount = res[0].getValue('formulanumeric', null, 'sum');
console.log(rowCount);
To get the total number of records, the only way is do a saved search, an ideal way to do such search is using nlobjSearch
Below is a sample code for getting infinite search Results and number of records
var search = nlapiLoadSearch(null, SAVED_SEARCH_ID).runSearch();
var res = [],
currentRes;
var i = 0;
while(i % 1000 === 0){
currentRes = (search.getResults(i, i+1000) || []);
res = res.concat(currentRes );
i = i + currentRes.length;
}
res.length or i will give you the total number of records and res will give you all the results.