Elastic is a search engine built on top of Lucene. We build Auto-complete capability with Elastic.
Setting up Elastic
Download the zip file from Elastic site. Extract the zip file to a suitable folder. From the bin folder, run service.bat install
. In the service manager, adjust the settings for the service. If you encounter Java errors, install Java runtime (8) from Oracle website. And finally, set the JAVA_HOME
environment variable to point to JVM location.
Auto-complete UI
Next, we convert a Textbox
into an auto-complete
widget. Please refer to an earlier post: Autocomplete textbox using jQuery. It is time to build the server API to fetch data from Elastic Search.
Fetching data from Elastic
We need two settings to create the client: Server URL and Default index. Using the Search
method in the client, we get the search results. For this example, search all the localities in the index. We use a wild-card search for the auto-complete. Finally, we iterate through the documents returned as search results and extract the relevant information.
public List<string> GetLocalities(string query) { var node = new Uri("http://localhost:9200"); var settings = new ConnectionSettings( node, defaultIndex: "my-application" ); var client = new ElasticClient(settings); query = string.Format("*{0}*", query.ToLower()); var searchResults = client.Search<LocalityDocument>(s => s.From(0) .Size(100) .Query(q => q.Wildcard(wqd => wqd.OnField("name") .Value(query) ))); return searchResults.Documents .Select(d => d.Name) .ToList(); }
Usually, the Elastic server is hosted at 9200
. Data is organized as indexes. Within an index, there are multiple document types. For our example, localities are retrieved from the my-application
index as a localitydocument
type.
Indexing data to Elastic
The indexing job is a background task. It usually happens periodically. If there is a new document or if there is an update to an existing document, we index the document. Indexing prepares the document for reverse lookup or search. For this example, we index localities data from the database.
static void CreateLocalityIndex() { using (var context = new DoctorPlus.Data.DoctorPlusContext()) { var node = new Uri("http://localhost:9200"); var settings = new ConnectionSettings( node, defaultIndex: "my-application" ); var client = new ElasticClient(settings); var localities = context.Localities.ToList(); foreach (var locality in localities) { var document = new LocalityDocument(); document.Name = locality; client.Index(document); Console.WriteLine("Indexed {0}", document.Name); } } }
We take localities from the database table. Use the settings to create an Elastic client. Pass the localities one-by-one to the Index
method of the client. Indexing is a background process. It is usually a console application triggered from a scheduled task.