Searching data is an interesting problem. Most of the application requires some sort of search implementations. Some need to provide very simple search functionalities whereas others require intelligent recommendation based searching techniques.
Today we are going to build a search implementation that can scale
with the needs of our application by querying different search algorithms/providers and serving combined results.
Search data source
The initial implementation is straightforward. We are going to do a text-based search over our data, and return whatever matches as the result.
So let’s write some code to make this happen
A very simple search query function. It’s going to take a
searchTerm and filter the
data according to that and returns us the result.
The result for this would be:
Woohoo!! It works and that’s great. It’s simple and gets us what we need.
But what if we want our search recommendations to be more intelligent. In addition to text-based search, we want to match based on other contexts as well.
For e.g if we search for business the result should be:
Our search system should be able to run different algorithms based on context and provide us with more intelligent results while keeping the simple external provider in place.
So let’s think about how to build such kind of recommendation system.
Let's start by defining a class around the current logic.
SearchRecSys class consists of
- Query which will query the search result and send us the right results
Let’s use this class in our code.
The result for this would be:
Now that it works as before, let's look at how to extend the provider to support more functionality. How we are going to do that? That’s where we are going to use multiple providers.
Every search recommendation algorithm will be a provider to our class and our class will query these providers one by one, combine all the results, and send them back through to the user.
Let’s go over the code and make it happen.
First of all, let’s create a new property called providers which will hold all of our provider functions.
Now let’s write a loadProviders method that will store providers as we pass them.
In case you are wondering the provider will be a function that will take a
searchTerm and returns a list of results.
Let’s modify our query method to support the provider.
Our query method will go through all the providers and store the result by each of those providers into results array and in the end once we have gone through all the providers then the results will be returned.
Let’s once again run our query but this time we have to pass a provider first.
So let’s convert our simple search function to a provider.
So we defined a new provider called searchUsingTerm. This function will take a searchTerm and data to query results from. It will return all the results which contain the searchTerm.
Now let’s register this provider.
And we are all set now.
Let’s use our query function again.
And the result for this would be:
Now we have the foundation in place and we can easily add any kind of provider to our search.
Let’s add a new provider to our search.
Now if you go through the above code there is a tiny bit of a difference. Instead of searching for a term we match the provided string with type of the search item and that’s a very simple provider but once we merge it with the searchUsingTerm it enables our search to be more intelligent.
Let’s search for business again.
The results that you will see now would be:
By dividing our search logic into different provider we built a system which lets you add as many providers you want making it an ideal solution for any kind of search problem.
Here is the whole source code:
I am available to give a public talk or for a meetup hit me up at email@example.com if you want to meet me.
Really loved this article?
Please subscribe to my blog. You will receive articles like this one directly in your inbox frequently.