Loading

Integration with Elastic.Ingest

Put attributes on your document type, declare a mapping context, and the ingest channel auto-configures itself. This page explains how the pieces connect.

// 1. Document with attributes
public class Product
{
    [Id]
    [Keyword]
    public string Sku { get; set; }

    [Text(Analyzer = "product_analyzer")]
    public string Name { get; set; }

    [Keyword]
    public string Category { get; set; }

    [ContentHash]
    [Keyword]
    public string Hash { get; set; }
}

// 2. Mapping context with configuration
[ElasticsearchMappingContext]
[Index<Product>(
    Name = "products",
    WriteAlias = "products-write",
    ReadAlias = "products-search",
    DatePattern = "yyyy.MM.dd.HHmmss",
    Configuration = typeof(ProductConfig))]
public static partial class CatalogContext;

// 3. Create a channel (strategy is fully auto-resolved)
var options = new IngestChannelOptions<Product>(transport, CatalogContext.Product.Context);
using var channel = new IngestChannel<Product>(options);

await channel.BootstrapElasticsearchAsync(BootstrapMethod.Failure);

foreach (var product in products)
    channel.TryWrite(product);
		

From this declaration, the channel auto-resolves:

Behavior Resolved to Why
Entity target Index [Index<T>] used
Bulk operation index (upsert) [Id] present
Bootstrap Component + index templates Index target
Provisioning Hash-based reuse [ContentHash] present
Alias Write + search aliases WriteAlias / ReadAlias set
Index naming products-2026.07.23.120000 DatePattern set
Index / DataStream /WiredStream EntityTarget Id attribute Bulk uses index ops(upserts enabled) Timestamp attribute Date-pattern index naming ContentHash attribute Hash-based provisioning(skip unchanged) BatchIndexDate attribute Batch date stamping WriteAlias / ReadAlias Alias strategy ConfigureAnalysis Settings component template
Attribute EntityTarget Bulk operation Bootstrap
[Index<T>] Index index (with [Id]) or create Component + index templates
[DataStream<T>] DataStream create (append-only) Component + data stream templates
[WiredStream<T>] WiredStream create (append-only) No-op (managed by Elasticsearch)
Attribute Generated delegate Effect
[Id] GetId Bulk headers include _id, enabling upserts
[Timestamp] GetTimestamp Date-pattern index naming
[ContentHash] GetContentHash Reuse existing index if hash matches
[BatchIndexDate] SetBatchIndexDate All batch documents share one index date
[LastUpdated] SetLastUpdated Each document gets the write time
Absent attribute Effect
No [Id] Bulk uses create (no upserts)
No [ContentHash] Always creates a new index on bootstrap
No [Timestamp] with DatePattern Compile-time error

The source generator populates an ElasticsearchTypeContext record at compile time. The ingest channel reads it at runtime.

When you call channel.BootstrapElasticsearchAsync():

  1. Reads settings and mappings JSON from the generated context
  2. Merges custom analysis (if ConfigureAnalysis is configured)
  3. Merges additional index settings (if IndexSettings is configured)
  4. Computes the template name from the context
  5. Checks the hash. If the template already exists with the same hash, skips the update
  6. Creates or updates the component template
  7. Creates or updates the index template
  8. Provisions the index according to the provisioning strategy

You only reference Elastic.Ingest.Elasticsearch. Everything else arrives transitively:

Elastic.Ingest.Elasticsearch
  └── Elastic.Mapping (includes source generator)
  └── Elastic.Ingest.Transport
        └── Elastic.Channels