Mapping context and strategy resolution
The [Entity<>] attribute on your mapping context drives everything the channel does: what kind of Elasticsearch target to create, which templates to put in place, how to format bulk operations, and how to manage aliases. This page is the complete reference for how [Entity<>] parameters map to channel behavior.
[ElasticsearchMappingContext]
[Entity<Product>]
public static partial class MyContext;
With no parameters, [Entity<Product>] defaults to:
- Target:
EntityTarget.Index - Name:
product(type name, lowercased) - No aliases, no date pattern, no data stream settings
The Target parameter determines the fundamental ingestion strategy:
// Index (default) -- mutable documents, upserts, aliases
[Entity<Product>]
[Entity<Product>(Target = EntityTarget.Index)]
// Data stream -- append-only, automatic rollover
[Entity<LogEntry>(Target = EntityTarget.DataStream,
DataStreamType = "logs", DataStreamDataset = "myapp")]
// Wired stream -- serverless managed, no local bootstrap
[Entity<LogEntry>(Target = EntityTarget.WiredStream)]
| Index | DataStream | WiredStream | |
|---|---|---|---|
| Ingest | TypeContextIndexIngestStrategy |
DataStreamIngestStrategy |
WiredStreamIngestStrategy |
| Bulk operation | index (upsert) |
create (append) |
create (append) |
| Bootstrap | Component + index templates | Component + data stream templates | No-op |
| Provisioning | Hash-based reuse or always create | Always create | Always create |
| Alias | Configured or none | None | None |
Attributes on your document class further refine the resolved strategy:
| Attribute | Effect on strategy |
|---|---|
[Id] |
Bulk headers include _id field, enabling upserts instead of blind inserts |
[Timestamp] |
Required for data streams. Used for date-based index naming when DatePattern is set |
[ContentHash] |
Enables HashBasedReuseProvisioning -- the channel checks if the existing index has the same schema hash and reuses it instead of creating a new one |
[Keyword] |
Maps to keyword field type in the component template |
[Text] |
Maps to text field type in the component template |
[Dimension] |
Marks a TSDB dimension field (requires DataStreamMode = DataStreamMode.Tsdb) |
For EntityTarget.Index, these parameters control index naming and alias management:
[Entity<Product>(
Target = EntityTarget.Index,
Name = "products",
WriteAlias = "products",
ReadAlias = "products-search",
SearchPattern = "products-*",
DatePattern = "yyyy.MM.dd.HHmmss"
)]
- Index name (default: type name lowercased)
- Write alias for zero-downtime rotation
- Search alias spanning all indices
- Glob pattern matching all indices
- Time-stamped index names
| Parameter | Default | Effect |
|---|---|---|
Name |
Type name lowercased | Base index name |
WriteAlias |
None | Enables LatestAndSearchAliasStrategy |
ReadAlias |
None | Search alias spanning all matching indices |
SearchPattern |
None | Glob for matching indices in alias operations |
DatePattern |
None | Creates time-stamped index names (e.g. products-2026.02.15.120000) |
Shards |
-1 (omitted) | Number of primary shards |
Replicas |
-1 (omitted) | Number of replica shards |
RefreshInterval |
None | Index refresh interval |
| WriteAlias | ReadAlias | Strategy |
|---|---|---|
| Not set | Not set | NoAliasStrategy |
| Set | Set | LatestAndSearchAliasStrategy -- swaps write alias to latest index, search alias spans all |
For EntityTarget.DataStream, these parameters control the data stream naming convention {type}-{dataset}-{namespace}:
[Entity<LogEntry>(
Target = EntityTarget.DataStream,
DataStreamType = "logs",
DataStreamDataset = "myapp",
DataStreamNamespace = "production", // Default: "default"
DataStreamMode = DataStreamMode.Tsdb
)]
- Required: logs, metrics, traces, etc.
- Required: source identifier
- Default: DataStreamMode.Default
| Parameter | Default | Effect |
|---|---|---|
DataStreamType |
Required | Data category (logs, metrics, traces) |
DataStreamDataset |
Required | Source identifier |
DataStreamNamespace |
"default" |
Environment (production, staging) |
DataStreamMode |
Default |
Default, LogsDb, or Tsdb |
Data stream name: {type}-{dataset}-{namespace} (e.g. logs-myapp-production)
Use Variant to define multiple index configurations for the same document type:
[ElasticsearchMappingContext]
[Entity<Article>(
Target = EntityTarget.Index,
Name = "articles-lexical",
WriteAlias = "articles-lexical",
ReadAlias = "articles-lexical-search",
SearchPattern = "articles-lexical-*",
DatePattern = "yyyy.MM.dd.HHmmss"
)]
[Entity<Article>(
Target = EntityTarget.Index,
Name = "articles-semantic",
Variant = "Semantic",
WriteAlias = "articles-semantic",
ReadAlias = "articles-semantic-search",
SearchPattern = "articles-semantic-*",
DatePattern = "yyyy.MM.dd.HHmmss"
)]
public static partial class ArticleContext;
This generates:
ArticleContext.Article.Context(lexical, default variant)ArticleContext.ArticleSemantic.Context(semantic variant)
Use variants with IncrementalSyncOrchestrator to coordinate multiple indices over the same data. See semantic enrichment for an end-to-end example.
When the auto-resolved strategy isn't enough, use the IngestStrategies and BootstrapStrategies factory methods:
// Add 30-day retention to a data stream
var strategy = IngestStrategies.DataStream<LogEntry>(context, "30d");
var options = new IngestChannelOptions<LogEntry>(transport, strategy, context);
// Add ILM to an index
var strategy = IngestStrategies.Index<Product>(context,
BootstrapStrategies.IndexWithIlm("products-policy"));
var options = new IngestChannelOptions<Product>(transport, strategy, context);
See strategies for the complete factory method reference.