Extending Salesforce Search with Azure Search using Logic Apps

Hi this time we want to bring inside the Salesforce platform the power of Azure search having as objective to index directly Salesforce entities.

Why this? Salesforce search is not enough? Of course Salesforce search capabilities are great but we can make it even greater if we can have things like fuzzy search, suggestions,etc.. that Azure Search offers out of the box.

How to achieve this? We can do a minimal project that can demonstrate quickly how we can add this functionality with ZERO impacts on existing Salesforce entities (no additional triggers or change in your existing code) but only a couple of additional visual force pages if you want.

The idea is to use Azure Logic Apps to detect record changes in Salesforce objects and refresh the azure search index when this happens.

Step 1 : Create the Azure Search Index Definition

We can use the rest API or directly the azure portal, let’s see the rest raw api call:


POST https://yoursearchservice.search.windows.net/indexes?api-version=2015-02-28
api-key: [yourApiKey]
Content-Type: application/json
{
"name": "myindex",
"fields": [
{"name": "id", "type": "Edm.String","key": true, "searchable": false},
{"name": "FirstName", "type": "Edm.String"},
{"name": "LastName", "type": "Edm.String"},
{"name": "Email", "type": "Edm.String"}
],
"suggesters": [
{
"name": "sg",
"searchMode": "analyzingInfixMatching",
"sourceFields": ["LastName"]
}
]
}

As you can see a real simple example with just SalesforceId, firstname, lastname and email indexed (we plan to index the Contact Objects). We add the suggester on the lastname, so you can test that even misspelling a surname the azure search will give you anyway a good tip on the person you wanted to find.

Step 2: Create an Azure Logic App

Here another simple process to put in place, with some minor complications due to the fact that search rest api do not expose still a good swagger definition so we have to go direct with http. We first login in salesforce with salesforce connector, then we pick the contact as object to watch.

sample

Here the code view of the Azure Logic App:


{
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"HTTP": {
"inputs": {
"body": "{'value': [{'@search.action': 'upload','id': '@{triggerBody()?['Id']}','FirstName': '@{triggerBody()?['FirstName']}','LastName': '@{triggerBody()['LastName']}','Email': '@{triggerBody()?['Email']}' }]}",
"headers": {
"Content-Type": "application/json",
"api-key": "yourapikey"
},
"method": "POST",
"uri": "https://yoursearchservice.search.windows.net/indexes/myindex/docs/index?api-version=2015-02-28"
},
"runAfter": {},
"type": "Http"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {
"$connections": {
"defaultValue": {},
"type": "Object"
}
},
"triggers": {
"When_an_object_is_modified": {
"inputs": {
"host": {
"api": {
"runtimeUrl": "https://logic-apis-westeurope.azure-apim.net/apim/salesforce"
},
"connection": {
"name": "@parameters('$connections')['salesforce']['connectionId']"
}
},
"method": "get",
"path": "/datasets/default/tables/@{encodeURIComponent(encodeURIComponent('Contact'))}/onupdateditems"
},
"recurrence": {
"frequency": "Minute",
"interval": 1
},
"splitOn": "@triggerBody()?.value",
"type": "ApiConnection"
}
}
}

So what are we doing here?
Well every minute we check if any contact is changed and if yes we update the azure search index with the new information.
Note the splitOn option we have OOB with this kind of trigger that allows us , if more than one record is changed during the minute , to invoke the azure search automatically for each of this records without doing anything more!

Step 3: Enjoy it!

Now you can build any visualforce page you like to call the azure search api and leverage the incredible features this technology offers to you!

Try the azure search suggestions api with some ajax to propose suggestions while the user types, your call center users will love that!

Tips: You can call azure search just using  http requests with api key on the header and use the automatic json deserialization libraries that are available on apex to convert the responses in objects that you can map to the visualforce tags.