Using Elasticsearch and NEST in NET

Lucas Garcia
7 min readJun 2, 2023

Elasticsearch is an amazing distributed search engine that can handle large volumes of data in real-time. It’s the perfect solution for developers who need advanced search capabilities like sorting, filtering, and text analysis. And the best part? You can easily use Elasticsearch in your .NET applications, thanks to the powerful client libraries available!

📚 The official Elasticsearch.Net library is a low-level client library that provides support for multiple versions of Elasticsearch. But if you want a more user-friendly and object-oriented interface for interacting with Elasticsearch, then NEST (Elasticsearch .NET) is the way to go! With NEST, you can map your .NET objects directly to document types in Elasticsearch, making it incredibly easy to index and retrieve data.

🚀 Getting started with Elasticsearch in .NET is a breeze. Simply add the corresponding NuGet package for the client library you want to use (like NEST), and you’re ready to go. And with this powerful tool at your disposal, you can easily build search functionality into your applications like never before.

In this first part So lets go check this out …

Elasticsearch Features for .NET Applications

Elasticsearch is a powerful search and analytics engine that offers a wide range of features for building robust applications. In this article, we’ll explore some of the key features provided by Elasticsearch and how they can be utilized in .NET applications. Let’s dive in!

1. 🔍 Advanced Text Search

Elasticsearch provides advanced text search capabilities, enabling you to perform complex and precise searches. You can utilize features like phrase matching, fuzzy search, prefix search, wildcard search, and proximity search to enhance your search experience.

// Perform a fuzzy search for the term "hello" in the "content" field
var searchResponse = client.Search<Person>(s => s
.Query(q => q
.Match(m => m
.Field(f => f.Content)
.Query("hello")
.Fuzziness(Fuzziness.Auto)
)
)
)

In the context of Elasticsearch, a fuzzy search is a type of search that allows for approximate matching of terms rather than exact matching. It is particularly useful when you want to find results that are similar to a given term but may contain slight variations, such as spelling mistakes, transpositions, or missing characters.

When performing a fuzzy search, Elasticsearch analyzes the search term and looks for documents that have terms similar to the provided query term. It calculates a similarity score based on the Levenshtein distance algorithm, which measures the number of single-character edits required to transform one term into another.

2. ⏰ Real-Time Indexing

Elasticsearch is designed for real-time indexing and search scenarios. It can handle large volumes of data and provide fast results even in high-traffic situations.

// Index a new document in real-time
var person = new Person { Id = 1, Name = "John Doe", Age = 30 };
var indexResponse = client.IndexDocument(person);

3. ➕ Aggregations

Aggregations in Elasticsearch allow you to perform real-time data analysis and summarization. You can calculate statistical metrics, perform grouping, extract unique values, create histograms, and more.

// Perform a date histogram aggregation to analyze the distribution of documents over time
var searchResponse = client.Search<Person>(s => s
.Aggregations(a => a
.DateHistogram("documents_over_time", dh => dh
.Field(f => f.Timestamp)
.CalendarInterval(DateInterval.Month)
)
)
);

4. 🌍 Geospatial Search

Elasticsearch provides built-in support for geospatial search and analysis. You can store points, shapes, and geographic polygons and perform proximity queries, region filtering, and distance calculations.

// Perform a geo-distance query to find documents within a certain radius of a specific location
var searchResponse = client.Search<Person>(s => s
.Query(q => q
.GeoDistance(gd => gd
.Field(f => f.Location)
.Distance("10km")
.Location(40.7128, -74.0060)
)
)
);

5. 📝 Text Analysis

Elasticsearch offers powerful text analysis capabilities, including tokenization, filtering, normalization, and stemming. You have fine-grained control over how your documents are processed during indexing and search.

// Define a custom analyzer with tokenizers and filters
var createIndexResponse = client.CreateIndex("my-index", c => c
.Settings(s => s
.Analysis(a => a
.Tokenizers(t => t
.Whitespace("my-tokenizer")
)
.Analyzers(an => an
.Custom("my-analyzer", ca => ca
.Tokenizer("my-tokenizer")
.Filters("lowercase", "stop", "stemmer")
)
)
)
)
.Map<Person>(m => m
.Properties(p => p
.Text(t => t
.Name("content")
.Analyzer("my-analyzer")
)
)
)
);

6. 👁‍🗨Filters

In addition to queries, Elasticsearch provides filters for document filtering based on specific criteria. Filters can be used to narrow down the search to a subset of documents or to apply additional constraints to the results.

// Apply a filter to retrieve documents with an age greater than 30
var searchResponse = client.Search<Person>(s => s
.Query(q => q
.Bool(b => b
.Filter(f => f
.Range(r => r
.Field(f => f.Age)
.GreaterThan(30)
)
)
)
)
);

These are just a few examples of the features provided by Elasticsearch. There are many more features available, such as suggestions, highlighting, sorting, data pipelines, and integrations with other popular tools. The official Elasticsearch documentation is a great resource for more detailed information.

NEST x Elasticsearch : Which to chose?

When working with Elasticsearch in .NET applications, you have the option to use NEST (Elasticsearch .NET), a high-level client library built on top of Elasticsearch.Net. While Elasticsearch.Net provides a low-level interface for Elasticsearch, NEST adds convenience, simplicity, and additional features that make working with Elasticsearch in .NET more developer-friendly. Here’s why you might consider using both NEST and Elasticsearch.Net:

1. 🎯 Simplified API

NEST offers a simplified and strongly-typed API that aligns with .NET conventions. Its fluent and intuitive syntax makes Elasticsearch operations easier to work with in .NET applications.

2. 📚 Mapping to POCO objects

NEST allows you to define Plain Old CLR Objects (POCOs) to represent your documents. It automatically maps these objects to Elasticsearch data structures, simplifying indexing and retrieval. Instead of dealing with JSON directly, you can work with familiar .NET objects.

3. 🧩 LINQ support

NEST integrates LINQ (Language Integrated Query) expressions, enabling you to write expressive queries using LINQ syntax. This facilitates complex querying, filtering, sorting, and aggregations on your data.

4. 🧬 Serialization and deserialization

NEST handles serialization and deserialization of .NET objects to JSON, ensuring seamless interaction with Elasticsearch. It offers configuration options for customizing serialization, such as ignoring properties, applying converters, and controlling field name mappings.

5.🗄️ Index management

NEST simplifies index management tasks like creating, deleting, and updating indexes. It provides methods and helpers for handling index settings, mappings, and aliases, allowing programmatic index management.

6. ✅ Integration with other features

NEST integrates with various Elasticsearch features like pipelines, analyzers, ingest nodes, and scripts. Dedicated methods and abstractions in NEST make these features easily accessible from your .NET application.

7. 🔄 Compatibility and versioning

NEST is designed to be compatible with specific Elasticsearch versions, ensuring you can leverage the latest Elasticsearch enhancements. It provides version-specific NuGet packages, allowing you to select the appropriate NEST version for your Elasticsearch version.

Using both NEST and Elasticsearch.Net together empowers you to benefit from NEST’s simplicity and convenience while retaining access to Elasticsearch.Net’s low-level capabilities when necessary.

In summary, NEST enhances Elasticsearch usage in .NET applications by providing a higher-level API with simplified syntax, POCO mapping, LINQ support, serialization/deserialization, index management, feature integration, and version compatibility. This combination of NEST and Elasticsearch.Net enables seamless and efficient Elasticsearch integration in your .NET projects. Check here the official NEST documentation

Using Elasticsearch in a .NET 5+ Application

Step 1: Install Elasticsearch.Net and NEST packages

  • Open your .NET project in your preferred code editor.
  • Install the Elasticsearch.Net and NEST packages using NuGet Package Manager or the .NET CLI.
  • For NuGet Package Manager, search for “Elasticsearch.Net” and “NEST” and install them.
  • For .NET CLI, navigate to your project directory and run the following commands:
dotnet add package Elasticsearch.Net
dotnet add package NEST

Step 2: Set up Elasticsearch connection settings

  • In your code, add the necessary namespaces:
using Elasticsearch.Net;
using Nest;
  • Create an instance of the Elasticsearch client by providing the appropriate Elasticsearch server URL:
var connectionSettings = new ConnectionSettings
(
new Uri("http://localhost:9200"));
ElasticClient elasticClient = new ElasticClient(connectionSettings
);

Step 3: Index a document

  • Define a class to represent your document:
public class Person 
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
  • Index a document by calling the IndexDocumentAsync method:
Person person = new Person { Id = 1, Name = "John Doe", Age = 30 };
var indexResponse = await elasticClient.IndexDocumentAsync(person);

if (indexResponse.IsValid)
Console.WriteLine("Document indexed successfully!");

Step 4: Search for documents

  • Perform a search query using the SearchAsync method:
var searchResponse = await elasticClient.SearchAsync<Person>(s => s
.Query(q => q
.Match(m => m
.Field(f => f.Name)
.Query("John")
)
)
);

foreach (var hit in searchResponse.Hits)
{
Person person = hit.Source;
Console.WriteLine($"Name: {person.Name}, Age: {person.Age}");
}

Step 5: Handle errors and cleanup

  • Handle any potential errors by checking the IsValid property of the response object:
if (!indexResponse.IsValid)
{
Console.WriteLine("Failed to index the document!");
Console.WriteLine(indexResponse.ServerError?.ToString());
}
  • Dispose of the Elasticsearch client to release resources:
elasticClient.Dispose();

Remember to handle exceptions appropriately and customize the code based on your specific use case. This example demonstrates the basic steps of indexing a document and performing a search using Elasticsearch in a .NET 5+ application.

Please note that this is a simplified example, and in real-world scenarios, you may need to configure additional settings, mappings, or perform more advanced operations based on your requirements.

Don’t forget to connect with me on Linkedin… See you next time.

--

--

Lucas Garcia

Fullstack C# developer @ WEG. Now working on improving Engineering processes through code https://www.linkedin.com/in/lucasmggarcia22/