Efficient CRUD Operations with ElasticSearch and .NET Core API

Introduction to ElasticSearch

ElasticSearch is a powerful and highly scalable open-source search and analytics engine built on top of Apache Lucene. It is designed to handle large amounts of data and provide fast, distributed search capabilities. ElasticSearch is commonly used for various purposes, including full-text search, log analytics, real-time analytics, and data visualization.

Key Features of ElasticSearch

  1. Distributed Architecture: ElasticSearch is built to distribute data across multiple nodes, enabling horizontal scalability and high availability. It uses sharding and replication techniques to ensure data is distributed and replicated across the cluster.
  2. Full-Text Search: ElasticSearch provides robust full-text search capabilities, allowing you to perform complex search queries across structured and unstructured data. It supports features like filtering, faceting, highlighting, and relevance scoring.
  3. Real-Time Data: ElasticSearch is designed to handle real-time data ingestion and analytics. It allows you to index and search data in near real-time, making it suitable for applications that require up-to-date information and quick responses.
  4. Schema-less: ElasticSearch is schema-less, meaning you can index and search documents without predefining a strict schema. It dynamically maps and indexes data based on its structure, which provides flexibility and simplifies the data indexing process.
  5. RESTful API: ElasticSearch exposes a comprehensive RESTful API, allowing you to interact with the search engine using HTTP requests. This makes it easy to integrate ElasticSearch into various applications and programming languages.
  6. Aggregations and Analytics: ElasticSearch offers powerful aggregation capabilities for performing data analytics and generating meaningful insights. Aggregations allow you to group, filter, and perform calculations on data sets, enabling you to extract valuable information from your indexed documents.
  7. Integration Ecosystem: ElasticSearch integrates seamlessly with other components of the Elastic Stack, including Logstash for data ingestion, Kibana for data visualization and dashboarding, and Beats for lightweight data shippers. This ecosystem provides a comprehensive solution for managing and analyzing data.

ElasticSearch is widely adopted in a range of industries, including e-commerce, content management, log analysis, cybersecurity, and enterprise search. Its scalability, flexibility, and powerful search capabilities make it a popular choice for applications that require efficient and fast retrieval of structured and unstructured data.

Here's an example of performing CRUD operations using ElasticSearch and .NET Core API for managing products:

  1. Install Required NuGet Packages:

    • NEST (Elasticsearch.Net & NEST)
  2. Define the Product Model:

    using Nest;
    
    public class Product
    {
        [Keyword]
        public string Id { get; set; }
    
        [Text]
        public string Name { get; set; }
    
        [Number]
        public decimal Price { get; set; }
    
        // Add additional properties as needed
    }
  3. Configure ElasticSearch Connection:
    using Nest;
    
    public class ElasticSearchConfig
    {
        private readonly string _elasticSearchUrl = "http://localhost:9200";
        private readonly string _indexName = "products"; // Name of your index
    
        public ElasticClient GetClient()
        {
            var settings = new ConnectionSettings(new Uri(_elasticSearchUrl))
                .DefaultIndex(_indexName);
    
            return new ElasticClient(settings);
        }
    }
    
  4. Create the Product Service:
    using Nest;
    
    public class ProductService
    {
        private readonly ElasticClient _elasticClient;
    
        public ProductService(ElasticClient elasticClient)
        {
            _elasticClient = elasticClient;
        }
    
        public async Task<bool> AddProduct(Product product)
        {
            var indexResponse = await _elasticClient.IndexDocumentAsync(product);
            return indexResponse.IsValid;
        }
    
        public async Task<Product> GetProduct(string id)
        {
            var searchResponse = await _elasticClient.GetAsync<Product>(id);
            return searchResponse.Source;
        }
    
        public async Task<bool> UpdateProduct(Product product)
        {
            var updateResponse = await _elasticClient.UpdateAsync<Product>(product.Id, u => u.Doc(product));
            return updateResponse.IsValid;
        }
    
        public async Task<bool> DeleteProduct(string id)
        {
            var deleteResponse = await _elasticClient.DeleteAsync<Product>(id);
            return deleteResponse.IsValid;
        }
    }
  5. Create the Product Controller:
    using Microsoft.AspNetCore.Mvc;
    
    [ApiController]
    [Route("api/products")]
    public class ProductController : ControllerBase
    {
        private readonly ProductService _productService;
    
        public ProductController(ProductService productService)
        {
            _productService = productService;
        }
    
        [HttpPost]
        public async Task<IActionResult> Create(Product product)
        {
            var success = await _productService.AddProduct(product);
            if (success)
            {
                return Ok();
            }
            return BadRequest("Failed to create product.");
        }
    
        [HttpGet("{id}")]
        public async Task<IActionResult> Get(string id)
        {
            var product = await _productService.GetProduct(id);
            if (product != null)
            {
                return Ok(product);
            }
            return NotFound();
        }
    
        [HttpPut]
        public async Task<IActionResult> Update(Product product)
        {
            var success = await _productService.UpdateProduct(product);
            if (success)
            {
                return Ok();
            }
            return BadRequest("Failed to update product.");
        }
    
        [HttpDelete("{id}")]
        public async Task<IActionResult> Delete(string id)
        {
            var success = await _productService.DeleteProduct(id);
            if (success)
            {
                return Ok();
            }
            return BadRequest("Failed to delete product.");
        }
    }
  6. Register Dependencies in Startup.cs:
    using Nest;
    
    public class Startup
    {
        // ...
    
        public void ConfigureServices(IServiceCollection services)
        {
            // ...
    
            // Add ElasticSearch configuration and services
            services.AddSingleton<ElasticSearchConfig>();
            services.AddScoped<ElasticClient>(serviceProvider =>
            {
                var config = serviceProvider.GetRequiredService<ElasticSearchConfig>();
                return config.GetClient();
            });
    
            // Add ProductService
            services.AddScoped<ProductService>();
    
            // ...
        }
    
        // ...
    }

With these code examples, you can create a .NET Core API for CRUD operations on products using ElasticSearch as the data store.

Similar Articles