I've faced governance limit in a user event script...
# suitescript
a
I've faced governance limit in a user event script? how can I handle that? any solution?
s
You would need to revise the architecture.
e
You have a limit of 1000 units
would have to see code to help optimize it
d
Please post code and intent of code
s
It depends on what you're trying to accomplish. For example... If you are running multiple searches when you could do one to get all results...
a
I have 2 searches
one is for members of a group and another one is for phone calls record. if the members of that group doesn't have phone call record I'll create a phone call record. I don't have problem with small group but with a large group there is a problem
for example a group with 1k members
d
@Ali seeing code will help us
That being said…. I would suggest you think about a couple of possible solutions.
a
sure
d
1. try using query module instead of search 2. look at using a map/reduce 3. write a outside program using something like Python and use query/suite analytics to pull data and SOAP API to push back data where need be.
@Ali code is a bit difficult for me to read (I am not well versed in TS yet), but looking at the general flow I would strongly suggest a Map/Reduce approach.
a
thanks, any other solution?
d
@Ali the fundamental issue is how much data you are trying to work with and it looks like you have a n^2 here. You maybe able to skirt by now with another type of solution but if your N’s become bigger you are still going to smack into governance which will then ultimately lead to your solution being unstable. My preference for dealing with this type of problem would be to write a python program and work the data outside of NS……
m
Yeah, David's right
You perform a search to get a list of items
s
yes and aside from the governance you’re presumably holding your users up waiting for this process. you can put it in a suitelet or map/reduce and let it run asynchronously
m
then you perform a serach for each of those
d
@suitedev @erictgrubaugh you guys are the experts here, please chime in if you have better solutions.
a
how can I put it in a map/reduce and process asc?
d
@Ali don’t worry so much about the M/R portion just yet
m
a better way would be to combine all of the compain searches, like this:
[['internalid', 'is', group1], 'and', ['groupmember.phone', 'isnotempty', null], 'or', ['internalid', 'is', group2], 'and', ['groupmember.phone', 'isnotempty', null], 'or', ...]
and then to add a column to know which
groupmember
it is
☝️ 1
d
@Ali first thing to do would likely to be reworking your search into a join query and avoid the n^2
a
I'm not familiar with join query. how can i USE THAT?
d
can you post the code for
Copy code
createSearch
a
Copy code
({
        type: 'entitygroup',
        columns: [{ name: 'internalid', join: 'groupmember' }],
        filters: [['internalid', 'is', group], 'and', ['groupmember.phone', 'isnotempty', null]]
    }).run().each(res => {
        memberInternalIds.push(res.getValue({ name: 'internalid', join: 'groupmember' }) as string);
        return true;
    })
Copy code
({
    type: 'phonecall',
    columns: ['company', 'contact', 'phone'],
    filters: [['custevent_campaign_phone_join', 'is', campaignId]]
}).run().each(res => {
    searchResults.push({ id: res.id, company: res.getValue('company'), contact: res.getText('contact'), contactId: res.getValue('contact'), phone: res.getValue('phone') })
    return true
})
d
@Ali I got a call here in a few minutes, after that I will try to jump back in here…… but I am going to struggle reading TypeScript.
a
@David Durst thanks
s
@Ali What record are you running this on? Does this process need to be completed immediately?
a
campaign, yes.
j
fwiw theres only two lines of code that is typescript, the rest is all modern javascript syntaxes
Copy code
const memberInternalIds: string[] = []
Copy code
memberInternalIds.push(res.getValue({ name: 'internalid', join: 'groupmember' }) as string);
e
Don't put your search in a loop
j
^ for example, instead of searching once for each campaign
Copy code
['custevent_campaign_phone_join', 'is', campaignId]
e
ah as I now see @Michael Pope already suggested. Each search is using 10 units of your 1000, then each
lookupFields
uses another 1, then each
delete
uses 10, so you'll quickly run out of your 1000 if the deletions or searches have any sort of significant scale
j
do one search that gets all phonecalls for all campaigns
Copy code
['custevent_campaign_phone_join', 'anyof', [campaignIds]]
a
but the issue is not related to foreach search
there is only one group with 1k member and only one campaign id
so that for each basically will run once and same for campaign id
j
This can also be done in one search
Copy code
memberInternalIds.forEach(id => {
        let phoneCallData = lookupFields({
            type: Type.CONTACT,
            id,
            columns: ['company', 'internalid', 'phone', 'customer.isinactive']
        })
a
the issue I guess is creatign phone call for 1k memebrs
e
yes
j
unfortunately, unlike searches, theres no way to consolidate creating 1000 records
e
Creating records on the thousands scale should pretty much always be relegated to a Map/Reduce
a
so I have to pass the data from UE to M/R script to create records?
e
to create thousands of records, yes
j
yes, your only options are asynchronous to the user event i.e. the phone call records will not be there immediately
a
is that immediate?
because I have to refresh the campaign and see the result
e
No, it gets put in the queue immediately.
You're not going to be able to
a
great, many thanks all.
d
@erictgrubaugh couldn’t he use a restlet to do the campaign creation? and then call the restlet?
e
Restlet has 5k limit
So, technically, sure he could do that
But it also costs 10 units to send the request
so what are you saving?
NetSuite is not structured to do bulk creation of records in realtime as it is nearly always the case that you're on a massively shared database.
Whenever my scale is more than a couple records, it's automatic for me to put it in a Map/Reduce
Are there other creative solutions? Sure.