Search knowledge based using REST API efficiently

wakespirit
Kilo Guru

Dear all ,

I have some special case in Searching the knowledge base which are not working as expected using REST API.

The goal in exemple below is to return all KB where short description contains for instance "access VPN" or "VPN.

What I mean is that event if access keyword is missing I should be able to get "access vpn" result

For exemple :

https://myinstance.service-now.com/api/now/table/kb_knowledge?sysparm_query=short_descriptionLIKEaccess vpn 
– Fetches desired results (OK) as the whole string is provided

https://myinstance.service-now.com/api/now/table/kb_knowledge?sysparm_query=short_descriptionLIKEvpn 
– Not all results are return as access is missing (MISSING ARTICLES)

 

The only way we make it works is to specify the whole querry as below:

https://myinstance.service-now.com/api/now/table/kb_knowledge?sysparm_query=short_descriptionLIKEacc... 
– Fetches desired results

 1st Query fetches the desired results only if all words Access and VPN are in sequence. If you change the sequence, no results are returned.

2nd Query does not fetch all the results. As word access is missing, it won’t return the results with Access and VPN in short_description

 3rd Query fetches all desired results; However as you can see I’ll have to append all the words with prefix short_descriptionLIKE. This will be a too long query if I ma more criterai.

For example, consider someone searching for kb with ‘I want to know how to get access to my application on Mobile using F5’.

Then by this long sentence I should be able to retrive any Kb wich has suitable matching short description. Which means that short descritpion can be only "access application on mobile".

Any idea how to handle such sear result ?

 

regards

1 ACCEPTED SOLUTION

moers
Giga Contributor

Hi wakespirit

the stop words list must have the same case as the query.

var stopWords = gs.getProperty('stopword.list').toString().toLowerCase().split(/[,\s]+/);

check if the stopWords an array? Format must be "term a, term b, etc";

gs.info(Array.isArray(stopWords))

same with queryArray

var arrayUtil = new ArrayUtil();

var queryArray = arrayUtil.diff(querySplit, stopWords); (querySplit - stopWords)

gs.info(Array.isArray(queryArray) + ' : '  + JSON.stringify(queryArray))

if query is an array, query.join('^') results in short_descriptionLIKEsegment_1^short_descriptionLIKEsegment_2 (desc contains [0] AND desc contains [1] AND....)

you can print the query with gs.info(kb.getEncodedQuery())

response.setBody(kb); might not work as kb is a GlideRecord object, create a json object e.g. 

response.setBody({ id : kb.getValue('sys_id'), desc : kb.getValue('short_description)});

 

Cheers

Bori 

View solution in original post

13 REPLIES 13

asifnoor
Kilo Patron

Instead of LIKe, why don't you try CONTAINS and use the word which is MUST to have. Then you should get all desired results.

Mark the answer as correct if this works.

Yes I can do that If I know in advance the MUST have keyword pout of the string.

But imagine you are in a chat bot and you ask the question :

I want to know how to get access to my application on Mobile using F5'

I have no idea in this sentence which keyword should I use as the CONTAINS MUST to have ?

What would be the approach to get the correct result done?

 

You can do this with script like this. It basically takes your string and breaks it into multiple words and build an API url.

var str="I want to know how to get access to my application on Mobile using F5";

//assuming space as a delimeter, let us break this into multiple strings
str = str.split(" ");
var count=0;
var query="short_description"; //the field in which you want to search

for (i=0;i<str.length;i++) {
  if(str[i].length>3) {
    //only then we will consider it to search, otherwise basic keywords like I an or am all those will be considered. so checking whether the word length is > 3.
    count++;
    if(count ==1) {
      query=query+"LIKE"+str[i];
    } else {
      query=query+"^ORshort_descriptionLIKE"+str[i];
   }
  }
}

//Now you can use this query variable and call the API like this

var url ="https://"+gs.getProperty("instance_name")+".service-now.com/api/now/table/kb_knowledge?sysparm_query="+query;

gs.print("API url is "+url);

 

Kindly mark the answer as correct and helpful if this works for you.

Thnaks for your reply.

Where can I define this script in order to creat teh variable and use that variable in REST API explorer for testing for instance ?

 Idea is to call the search through REST API outsided of ServiceNow

regards