This article demonstrates how to use elastic search in .net applications using Nest client. I will demonstrate how to set up Elastic search in a developer machine and how to communicate with Elastic from a .net application. I am going to cover the below points in the article.
- How to download and install Elastic in the developer system?
- How to communicate from the .net application?
- Create an Index in Elastic
- Insert data in the Index.
- Read data from Index.
What is elastic search?
According to the official Elastic search website, Elastic. co
"Elasticsearch is a distributed, open-source search and analytics engine for all types of data, including textual, numerical, geospatial, structured, and unstructured.
Elasticsearch is built on Apache Lucene and was first released in 2010 by Elasticsearch N.V. (now known as Elastic). Known for its simple REST APIs, distributed nature, speed, and scalability, Elasticsearch is the central component of the Elastic Stack, a set of open source tools for data ingestion, enrichment, storage, analysis, and visualization. Commonly referred to as the ELK Stack (after Elasticsearch, Logstash, and Kibana), the Elastic Stack now includes a rich collection of lightweight shipping agents known as Beats for sending data to Elasticsearch."
Let's start step by step. First, we will install Elastic in the developer machine.
How to download and install Elastic in a developer system?
- Download Elastic Search from this link Elastic Search 7.8 and follow the below steps to configure it.
- Once you click on the above link you will get Elastic search in the .zip folder. Extract it and install it in the local system.
- After File Extraction click on ElasticSearch.bat file.
- Once you click on the elasticsearch.bat file your server will be up and running like the below screen:
- If elasticsearch.bat doesn't run properly then you need to check if jdk is installed in the system or not. If not then you need to install it. Here we have used Elasticsearch.Nest client - 7.8 and jdk-14.0.1
- Add a new project from Visual Studio and add Elasticsearch.Nest reference from nuget package manager as below.
Once a reference is added you need to create an Elastic client connecter which is going to communicate with Elasticsearch. I have added the code snippet below.
public class ElasticSearchClient
{
#region Elasticsearch Connection
public ElasticClient EsClient()
{
var nodes = new Uri[]
{
new Uri("http://localhost:9200/"),
};
var connectionPool = new StaticConnectionPool(nodes);
var connectionSettings = new ConnectionSettings(connectionPool).DisableDirectStreaming();
var elasticClient = new ElasticClient(connectionSettings.DefaultIndex("productdetails"));
return elasticClient;
}
#endregion Elasticsearch Connection
}
Add model and controller for inserting document to index.
public class Products
{
public int ProductId { get; set; }
public string ProductName { get; set; }
public decimal Price { get; set; }
public string Description { get; set; }
public List<CheckBoxModel> Colors { get; set; }
public List<CheckBoxModel> Tags { get; set; }
}
public class CheckBoxModel
{
public int Value { get; set; }
public string Text { get; set; }
public bool IsChecked { get; set; }
}
public class ProductController : Controller
{
private readonly ElasticSearchClient _esClient;
public ProductController()
{
_esClient = new ElasticSearchClient();
}
// GET: Product
public ActionResult Index()
{
return RedirectToAction("Create");
}
// GET: Product/Create
public ActionResult Create()
{
var colors = new List<CheckBoxModel>()
{
new CheckBoxModel { Value = 1, Text = "Red", IsChecked = true },
new CheckBoxModel { Value = 1, Text = "Green", IsChecked = false },
new CheckBoxModel { Value = 1, Text = "Orange", IsChecked = false },
new CheckBoxModel { Value = 1, Text = "Blue", IsChecked = false },
new CheckBoxModel { Value = 1, Text = "Purple", IsChecked = false },
new CheckBoxModel { Value = 1, Text = "Yellow", IsChecked = false },
};
var tags = new List<CheckBoxModel>()
{
new CheckBoxModel { Value = 1, Text = "Mens wear", IsChecked = true },
new CheckBoxModel { Value = 1, Text = "Ladies Wear", IsChecked = false },
new CheckBoxModel { Value = 1, Text = "New Arrival", IsChecked = false },
new CheckBoxModel { Value = 1, Text = "Top Brands", IsChecked = false },
new CheckBoxModel { Value = 1, Text = "Kids Wear", IsChecked = false },
new CheckBoxModel { Value = 1, Text = "Jeans", IsChecked = false },
};
var productDetails = new Products
{
Colors = colors,
Tags = tags
};
return View(productDetails);
}
// POST: Product/Create
[HttpPost]
public ActionResult Create(Products products)
{
try
{
var productDetail = new ProductDetails()
{
ProductId = products.ProductId,
ProductName = products.ProductName,
Price = products.Price,
Description = products.Description,
Colors = products.Colors.Where(x => x.IsChecked == true).Select(x => x.Text).ToArray(),
Tags = products.Tags.Where(x => x.IsChecked == true).Select(x => x.Text).ToArray()
};
// Insert product detail document to index
var defaultIndex = "productdetails";
var indexExists = _esClient.EsClient().Indices.Exists(defaultIndex);
if (!indexExists.Exists)
{
var response = _esClient.EsClient().Indices.Create(defaultIndex,
index => index.Map<ProductDetails>(
x => x.AutoMap()
));
}
var indexResponse1 = _esClient.EsClient().IndexDocument(productDetail);
return RedirectToAction("Create");
}
catch
{
return View();
}
}
}
Add the Product to the index using the below screen. Here I have added 10 products from this screen.
I have the below records as of now in the index which are inserted from the Add Product screen,
[
{
"productId": 1,
"productName": "Shirt",
"price": 1000.0,
"description": "Shirt is made from pure cotton. Very stylish shirt specially designed for men.",
"colors": [
"Red",
"Green",
"Orange",
"Purple",
"Yellow"
],
"tags": [
"Mens wear",
"New Arrival"
]
},
{
"productId": 2,
"productName": "Pures",
"price": 1200.0,
"description": "Hand made purse for Women. Designed from pure leather.",
"colors": [
"Red",
"Green",
"Purple",
"Yellow"
],
"tags": [
"New Arrival",
"Top Brands"
]
},
{
"productId": 3,
"productName": "Jacket",
"price": 1300.0,
"description": "Jackat is made from leather. specially designed for men and womens",
"colors": [
"Red",
"Green",
"Orange",
"Yellow"
],
"tags": [
"New Arrival",
"Top Brands"
]
},
{
"productId": 4,
"productName": "Blazer",
"price": 1400.0,
"description": "Hand made blazer which are very stylish and specially designed for man.",
"colors": [
"Red",
"Green",
"Orange",
"Blue",
"Purple",
"Yellow"
],
"tags": [
"Mens wear",
"Ladies Wear",
"New Arrival",
"Top Brands"
]
},
{
"productId": 5,
"productName": "Jeans Top",
"price": 1400.0,
"description": "Jeans is for men and women. Very good quality material with latest design",
"colors": [
"Blue"
],
"tags": [
"Mens wear",
"Ladies Wear",
"New Arrival",
"Jeans"
]
},
{
"productId": 6,
"productName": "Girl Dresses",
"price": 1500.0,
"description": "Girl dresses and casual wears",
"colors": [
"Red",
"Orange",
"Purple"
],
"tags": [
"Top Brands",
"Kids Wear"
]
},
{
"productId": 7,
"productName": "Jumpsuits",
"price": 500.0,
"description": "Girl jumpsuit with latest design",
"colors": [
"Orange",
"Blue",
"Purple"
],
"tags": [
"New Arrival",
"Top Brands",
"Kids Wear",
"Jeans"
]
},
{
"productId": 8,
"productName": "Kurta",
"price": 1700.0,
"description": "Men traditional and designer kurta with latest design",
"colors": [
"Red",
"Green",
"Orange",
"Purple",
"Yellow"
],
"tags": [
"Mens wear",
"New Arrival",
"Top Brands"
]
},
{
"productId": 9,
"productName": "chididar",
"price": 1400.0,
"description": "Ladies chudidar dress with quality fabric.",
"colors": [
"Red",
"Green",
"Orange",
"Blue",
"Purple",
"Yellow"
],
"tags": [
"Ladies Wear",
"New Arrival",
"Top Brands"
]
},
{
"productId": 10,
"productName": "Purse",
"price": 600.0,
"description": "Purse is made from pure leather. 100% pure leather is used to make this purse with great finishing.",
"colors": [
"Red",
"Green",
"Orange",
"Blue",
"Purple",
"Yellow"
],
"tags": [
"Ladies Wear",
"Top Brands"
]
}
]
Now let's add the code snippet for Searching data from the elastic index.
public class ProductDetails
{
public int ProductId { get; set; }
public string ProductName { get; set; }
public decimal Price { get; set; }
public string Description { get; set; }
public string[] Colors { get; set; }
public string[] Tags { get; set; }
}
public class SearchController : Controller
{
private readonly ElasticSearchClient _esClient;
public SearchController()
{
_esClient = new ElasticSearchClient();
}
[HttpGet]
public ActionResult Search()
{
return View("Search");
}
public JsonResult DataSearch(string term)
{
var responsedata = _esClient.EsClient().Search<ProductDetails>(s => s.Source()
.Query(q => q
.QueryString(qs => qs
.AnalyzeWildcard()
.Query("*" + term.ToLower() + "*")
.Fields(fs => fs
.Fields(f1 => f1.ProductName,
f2 => f2.Description,
f3 => f3.Tags,
f4 => f4.Colors
)
)
)
)
);
var datasend = responsedata.Documents.ToList();
return Json(datasend, behavior: JsonRequestBehavior.AllowGet);
}
}
In the above code snippet, I have added a model with properties and a search controller for searching data from the elastic index. I have used wild card search for 4 fields, ProductName, Description, Tags, and colors. If the search term is available in any of the fields then the search method will return all matched documents as a response.
- Now let's search with a few terms which will return wildcard. Search in elastic search, i.e. search terms "shirt", Shirt is there in the product name so only one record is returned, as below.
- Now take one more example. Search with the term "men". This word exists in the below documents so it returns 6 documents as below.
- Now let's search with a color column; i.e. Yellow.
- Let's search one more scenario for the tags column with the term "Top Brand"
Conclusion
In this article, we learned about how to configure elastic search in a developer machine, how to create the index and insert the document, and how to search data using wildcard search on multiple fields. This is a simple example of wildcard search in Elasticsearch using nest client. There are lots of options available in elastic search to write search queries, filters, Analyzer, Tokenizer, and many more which I am going to cover in upcoming articles.