GaoXinLibrary.ElasticSearch
1.0.1
dotnet add package GaoXinLibrary.ElasticSearch --version 1.0.1
NuGet\Install-Package GaoXinLibrary.ElasticSearch -Version 1.0.1
<PackageReference Include="GaoXinLibrary.ElasticSearch" Version="1.0.1" />
<PackageVersion Include="GaoXinLibrary.ElasticSearch" Version="1.0.1" />
<PackageReference Include="GaoXinLibrary.ElasticSearch" />
paket add GaoXinLibrary.ElasticSearch --version 1.0.1
#r "nuget: GaoXinLibrary.ElasticSearch, 1.0.1"
#:package GaoXinLibrary.ElasticSearch@1.0.1
#addin nuget:?package=GaoXinLibrary.ElasticSearch&version=1.0.1
#tool nuget:?package=GaoXinLibrary.ElasticSearch&version=1.0.1
GaoXinLibrary.ElasticSearch
Elasticsearch 9.x 简化封装库,基于 Elastic.Clients.Elasticsearch 9.x,支持 .NET 8/9/10。
安装
dotnet add package GaoXinLibrary.ElasticSearch
特性
- 简化 CRUD — 一行代码完成文档的增删改查
- 搜索构建器 —
BuildSearch<T>()流式构建 Bool 查询 + 排序 + 过滤 + 高亮 + 分页 - 统一字段映射 —
[ElasticField]特性统一配置字段类型、分析器、忽略、Completion - 多种分析器 — 内置 Standard / Simple / Whitespace / IK / CJK 等分析器支持
- IK 分词 — 开箱即用的
ik_smart/ik_max_word分词支持 - Suggest 自动补全 — Completion Suggester,支持单字段/多字段、模糊匹配、通配符回退
- 高亮搜索 — 内置高亮标签封装,搜索结果自动携带
Highlights字典 - 通配符/前缀搜索 —
WildcardSearchAsync/PrefixSearchAsync,支持不区分大小写 - 表达式局部更新 —
UpdateFieldsAsync通过表达式选择字段进行局部更新 - 索引映射更新 —
UpdateIndexMappingAsync在线更新索引映射(新增字段) - 索引设置更新 —
UpdateIndexSettingsAsync动态修改副本数、刷新间隔、结果窗口等 - 索引生命周期 — 刷新、Reindex、关闭/打开、别名管理
- 批量操作 —
BulkIndexAsync/BulkUpdateAsync/BulkDeleteAsync - 滚动搜索 —
ScrollAllAsync适合大数据量全量导出 - 滚动批量更新 —
ScrollUpdateAsync按查询条件滚动批量更新 - 分页搜索 — 内置分页封装,返回总页数、是否有上/下页
- 聚合查询 — 简化的 Terms 聚合接口
- 索引管理 — 根据特性自动创建索引 + 字段映射 + 设置更新 + 别名
- DI 注入 —
AddElasticsearch()一行注册所有服务 - 底层客户端 — 随时通过
Client属性访问底层ElasticsearchClient
快速开始
1. 注册服务
builder.Services.AddElasticsearch(options =>
{
options.Urls = ["http://localhost:9200"];
options.DefaultIndex = "my-app";
options.Username = "elastic";
options.Password = "changeme";
options.DefaultAnalyzer = AnalyzerType.IkSmart;
});
2. 定义文档
[ElasticsearchIndex("products")]
public class Product
{
public string Id { get; set; } = "";
[ElasticField(FieldType = ElasticFieldType.Text, Analyzer = AnalyzerType.IkMaxWord, SearchAnalyzer = AnalyzerType.IkSmart,
EnableKeywordSubField = true)]
[ElasticCompletion(Analyzer = AnalyzerType.IkMaxWord)]
public string Name { get; set; } = "";
[ElasticField(FieldType = ElasticFieldType.Text, Analyzer = AnalyzerType.IkSmart)]
public string Description { get; set; } = "";
[ElasticField(FieldType = ElasticFieldType.Keyword)]
[ElasticCompletion]
public string SupplierNo { get; set; } = "";
[ElasticField(FieldType = ElasticFieldType.Completion, Analyzer = AnalyzerType.IkMaxWord)]
public string Suggest { get; set; } = "";
[ElasticField(FieldType = ElasticFieldType.Keyword)]
public string Category { get; set; } = "";
[ElasticField(FieldType = ElasticFieldType.Double)]
public decimal Price { get; set; }
[ElasticField(FieldType = ElasticFieldType.Date, DateFormat = "yyyy-MM-dd HH:mm:ss||epoch_millis")]
public DateTime CreatedAt { get; set; }
[ElasticField(Ignore = true)]
public string InternalCode { get; set; } = "";
// ── Object / Nested 嵌套类型 ──
[ElasticField(FieldType = ElasticFieldType.Object)]
public ProductCategory? ProductCategory { get; set; }
[ElasticField(FieldType = ElasticFieldType.Nested)]
public List<ProductTag>? Tags { get; set; }
}
/// <summary>Object 子类型,属性同样使用 [ElasticField] 标注</summary>
public class ProductCategory
{
[ElasticField(FieldType = ElasticFieldType.Keyword)]
public string Value { get; set; } = "";
[ElasticField(FieldType = ElasticFieldType.Integer)]
public int CategoryId { get; set; }
}
/// <summary>Nested 子类型,支持嵌套查询</summary>
public class ProductTag
{
[ElasticField(FieldType = ElasticFieldType.Keyword)]
public string Name { get; set; } = "";
[ElasticField(FieldType = ElasticFieldType.Double)]
public double Score { get; set; }
}
Object / Nested 说明: 将
FieldType设置为Object或Nested时,库会自动递归读取子类型的[ElasticField]特性,生成嵌套映射。支持直接类型(ProductCategory)和集合类型(List<ProductTag>、ProductTag[]等)。
3. 使用服务
public class ProductService
{
private readonly IElasticsearchService _es;
public ProductService(IElasticsearchService es) => _es = es;
public async Task Demo()
{
// ── 确保索引存在(自动创建 + 字段映射) ──
await _es.EnsureIndexAsync<Product>();
// ── 索引文档 ──
await _es.IndexAsync(new Product
{
Id = "1",
Name = "华为 Mate 60 Pro",
Description = "搭载麒麟芯片的旗舰手机",
Suggest = "华为 Mate 60 Pro",
Category = "手机",
Price = 6999
}, id: "1");
// ── 获取文档 ──
var product = await _es.GetAsync<Product>("1");
// ── 批量获取 ──
var products = await _es.MultiGetAsync<Product>(["1", "2", "3"]);
// ── 更新文档 ──
await _es.UpdateAsync<Product>("1", new { Price = 5999 });
// ── 表达式局部更新(推荐) ──
await _es.UpdateFieldsAsync<Product>("1", ct: default,
(x => x.Price, 5999m),
(x => x.Name, "华为 Mate 70 Pro"));
// ── 全文搜索(字符串字段名) ──
var results = await _es.FullTextSearchAsync<Product>(
"华为手机", ["name", "description"],
analyzerType: AnalyzerType.IkSmart);
// ── 全文搜索(表达式选择字段,自动解析 [ElasticField] 字段名,推荐) ──
var results2 = await _es.FullTextSearchAsync<Product>(
"华为手机", [x => x.Name, x => x.Description],
analyzerType: AnalyzerType.IkSmart);
// ── 分页搜索 ──
var paged = await _es.SearchPagedAsync<Product>(
"手机", [x => x.Name], page: 1, pageSize: 10);
Console.WriteLine($"共 {paged.Total} 条,第 {paged.Page}/{paged.TotalPages} 页");
// ── 高亮搜索 ──
var highlighted = await _es.HighlightSearchAsync<Product>(
"华为", [x => x.Name, x => x.Description],
preTags: "<mark>", postTags: "</mark>");
// ── 自动补全 ──
var suggestions = await _es.SuggestAsync<Product>(
"华为", x => x.Suggest, size: 5, fuzzy: true);
foreach (var s in suggestions.Suggestions)
Console.WriteLine($"建议: {s}");
// ── 通配符搜索 ──
var wildcardResults = await _es.WildcardSearchAsync<Product>(
x => x.Name, "华为*", size: 10);
// ── 前缀搜索 ──
var prefixResults = await _es.PrefixSearchAsync<Product>(
x => x.Category, "手", size: 10);
// ── 精确匹配 ──
var exact = await _es.TermSearchAsync<Product>(x => x.Category, "手机");
// ── 批量索引 ──
var batch = Enumerable.Range(1, 100).Select(i => new Product
{
Id = i.ToString(),
Name = $"商品{i}",
Category = "测试",
Price = i * 10
});
await _es.BulkIndexAsync(batch);
// ── 批量更新 ──
await _es.BulkUpdateAsync<Product>(new Dictionary<string, object>
{
["1"] = new { Price = 4999 },
["2"] = new { Price = 3999 }
});
// ── 聚合 ──
var agg = await _es.TermsAggregationAsync<Product>(x => x.Category, size: 5);
// ── 计数 ──
var count = await _es.CountAsync<Product>();
// ── 多字段自动补全(带通配符回退) ──
var multiSuggest = await _es.SuggestMultiFieldAsync<Product>(
"华为", [x => x.Name, x => x.Suggest],
size: 10, fuzzy: true, wildcardFallback: true);
// ── 高亮搜索结果中提取高亮 ──
var hlResult = await _es.HighlightSearchAsync<Product>(
"华为", [x => x.Name, x => x.Description],
preTags: "<mark>", postTags: "</mark>");
for (int i = 0; i < hlResult.Documents.Count; i++)
{
if (hlResult.Highlights.TryGetValue(i, out var fields))
{
if (fields.TryGetValue("name", out var nameHl))
Console.WriteLine($"高亮名称: {string.Join("", nameHl)}");
}
}
// ── 滚动搜索(大数据量导出) ──
var allProducts = await _es.ScrollAllAsync<Product>(batchSize: 500);
// ── 滚动批量更新(按条件批量更新所有文档) ──
var updated = await _es.ScrollUpdateAsync<Product>(
q => q.Query(qq => qq.Term(t => t.Field("category").Value("手机"))),
new { Price = 4999 },
batchSize: 5000);
Console.WriteLine($"共更新 {updated} 个文档");
// ── 更新索引映射(新增字段时使用) ──
await _es.UpdateIndexMappingAsync<Product>();
// ── 更新索引设置(动态设置,立即生效) ──
await _es.UpdateIndexSettingsAsync("products", settings => settings
.NumberOfReplicas(2)
.RefreshInterval("30s")
.MaxResultWindow(50000));
// ── 根据 [ElasticsearchIndex] 特性更新索引设置 ──
await _es.UpdateIndexSettingsAsync<Product>();
// ── 刷新索引(使最近写入对搜索可见) ──
await _es.RefreshIndexAsync<Product>();
// ── Reindex(索引迁移 / 字段类型变更) ──
var reindexed = await _es.ReindexAsync("products", "products_v2");
Console.WriteLine($"共迁移 {reindexed} 个文档");
// ── 关闭 / 打开索引(修改静态设置时使用) ──
await _es.CloseIndexAsync("products");
// ... 修改静态设置 ...
await _es.OpenIndexAsync("products");
// ── 索引别名管理 ──
await _es.AddAliasAsync("products_v2", "products_alias");
var aliases = await _es.GetAliasesAsync("products_v2");
Console.WriteLine($"别名: {string.Join(", ", aliases)}");
await _es.RemoveAliasAsync("products_v2", "products_alias");
// ── 删除文档 ──
await _es.DeleteAsync<Product>("1");
// ── 按条件删除 ──
await _es.DeleteByQueryAsync<Product>(d => d
.Query(q => q.Term(t => t.Field("category").Value("测试"))));
// ── 删除索引 ──
await _es.DeleteIndexAsync("products");
}
}
4. 搜索构建器(推荐)
通过 BuildSearch<T>() 创建搜索构建器,支持 Bool 查询组合、排序、过滤、高亮、分页 等:
// ── 基本搜索 + 过滤 + 排序 ──
var result = await _es.BuildSearch<Product>()
.Must(q => q.Match(m => m.Field("name").Query("华为手机").Analyzer("ik_smart")))
.Filter(q => q.Term(t => t.Field("category").Value("手机")))
.Filter(q => q.Range(r => r.NumberRange(n => n.Field("price").Gte(1000).Lte(5000))))
.Sort(x => x.Price, SortOrder.Asc)
.SortByScore()
.Size(20)
.ExecuteAsync();
// ── 多条件搜索 + 高亮 + 分页 ──
var paged = await _es.BuildSearch<Product>()
.Must(q => q.MultiMatch(mm => mm.Query("华为").Fields(["name", "description"]).Analyzer("ik_smart")))
.Should(q => q.Term(t => t.Field("category").Value("手机")))
.MustNot(q => q.Term(t => t.Field("category").Value("配件")))
.Filter(q => q.Range(r => r.NumberRange(n => n.Field("price").Gte(100))))
.MinimumShouldMatch(0)
.Sort(x => x.Price, SortOrder.Asc)
.Highlight(x => x.Name, "<mark>", "</mark>")
.Highlight(x => x.Description, "<mark>", "</mark>")
.ExecutePagedAsync(page: 1, pageSize: 10);
Console.WriteLine($"共 {paged.Total} 条,第 {paged.Page}/{paged.TotalPages} 页");
// ── 纯过滤(不需要得分排序,性能最好) ──
var filtered = await _es.BuildSearch<Product>()
.Filter(q => q.Term(t => t.Field("category").Value("手机")))
.Filter(q => q.Range(r => r.DateRange(d => d.Field("createdAt").Gte("2024-01-01"))))
.Sort(x => x.CreatedAt, SortOrder.Desc)
.Size(50)
.ExecuteAsync();
// ── Source 过滤(只返回部分字段) ──
var partial = await _es.BuildSearch<Product>()
.Must(q => q.MatchAll(new MatchAllQuery()))
.SourceIncludes(x => x.Name, x => x.Price)
.Size(100)
.ExecuteAsync();
查询类型说明:
| 方法 | 作用 | 影响得分 | 典型场景 |
|---|---|---|---|
Must() |
必须匹配 | ✅ 是 | 关键词搜索、全文匹配 |
Should() |
可选匹配(提升得分) | ✅ 是 | 相关性提升、多条件可选 |
Filter() |
必须匹配 | ❌ 否 | 价格区间、分类、状态过滤 |
MustNot() |
排除匹配 | ❌ 否 | 排除特定分类、状态 |
5. 自定义搜索(DSL)
通过 SearchAsync 方法直接使用底层 DSL:
var result = await _es.SearchAsync<Product>(s => s
.Size(20)
.Query(q => q
.Bool(b => b
.Must(
m => m.Match(mm => mm.Field("name").Query("手机").Analyzer("ik_smart")),
m => m.Range(r => r.NumberRange(nr => nr.Field("price").Gte(1000).Lte(5000)))
)
)
)
.Sort(so => so.Field("price", f => f.Order(SortOrder.Asc)))
);
6. 直接使用底层客户端
var client = _es.Client;
var response = await client.SearchAsync<Product>(s => s.Indices("products").Size(5));
分析器类型
| 类型 | 值 | 说明 |
|---|---|---|
Default |
不指定 | 使用 ES 默认 |
Standard |
standard |
标准分析器(按 Unicode 规则分词) |
Simple |
simple |
简单分析器(按非字母字符拆分) |
Whitespace |
whitespace |
空白分析器(按空白字符拆分) |
Keyword |
keyword |
不分词(整个字段作为一个 Token) |
Pattern |
pattern |
模式分析器(按正则拆分) |
Cjk |
cjk |
中日韩分析器 |
IkSmart |
ik_smart |
IK 智能分词(粗粒度,适合搜索) |
IkMaxWord |
ik_max_word |
IK 最大化分词(细粒度,适合索引) |
字段类型
| 类型 | 说明 |
|---|---|
Auto |
自动推断(有分析器时为 Text,否则为 Keyword) |
Text |
全文本(支持分词) |
Keyword |
关键词(精确匹配、排序、聚合) |
Integer / Long / Float / Double |
数值类型 |
Date |
日期类型(支持自定义格式) |
Boolean |
布尔类型 |
Completion |
自动补全(Suggest) |
Nested |
嵌套对象 |
Object |
对象类型 |
GeoPoint |
地理位置 |
Ip |
IP 地址 |
Binary |
二进制 |
*Range |
范围类型 |
[ElasticField] 特性选项
| 选项 | 默认值 | 说明 |
|---|---|---|
FieldType |
Auto |
字段映射类型 |
Analyzer |
Default |
索引时分析器 |
SearchAnalyzer |
Default |
搜索时分析器(默认同 Analyzer) |
Ignore |
false |
忽略字段(不添加到索引映射中) |
FieldName |
null |
自定义 ES 字段名 |
MaxInputLength |
50 |
Completion 最大输入长度(仅 FieldType=Completion) |
DateFormat |
null |
日期格式 |
Store |
false |
是否存储原始值 |
Boost |
0 |
权重提升 |
EnableKeywordSubField |
false |
添加 .keyword 子字段(仅 Text 类型,用于精确匹配/排序/聚合) |
[ElasticCompletion] 特性选项
独立的自动补全子字段特性,可与 [ElasticField] 配合使用,在 Text / Keyword 字段上附加 .suggest 子字段。
| 选项 | 默认值 | 说明 |
|---|---|---|
SubFieldName |
"suggest" |
子字段名称(生成 fieldName.suggest) |
Analyzer |
Default |
自动补全分析器(默认同主字段 Analyzer) |
MaxInputLength |
50 |
最大输入长度 |
// Text 字段 + .keyword 子字段 + .suggest 自动补全
[ElasticField(FieldType = ElasticFieldType.Text, Analyzer = AnalyzerType.IkMaxWord, EnableKeywordSubField = true)]
[ElasticCompletion(Analyzer = AnalyzerType.IkMaxWord)]
public string Name { get; set; } = "";
// Keyword 字段 + .suggest 自动补全
[ElasticField(FieldType = ElasticFieldType.Keyword)]
[ElasticCompletion]
public string SupplierNo { get; set; } = "";
// 独立的 Completion 字段(不是子字段)
[ElasticField(FieldType = ElasticFieldType.Completion, Analyzer = AnalyzerType.IkMaxWord)]
public string Suggest { get; set; } = "";
配置选项
| 选项 | 默认值 | 说明 |
|---|---|---|
Urls |
["http://localhost:9200"] |
节点地址 |
DefaultIndex |
"default" |
默认索引 |
Username |
null |
用户名 |
Password |
null |
密码 |
ApiKey |
null |
API Key 认证 |
CertificateFingerprint |
null |
HTTPS 证书指纹 |
RequestTimeoutSeconds |
30 |
请求超时 |
DefaultAnalyzer |
Standard |
默认分析器 |
DefaultNumberOfShards |
1 |
默认分片数 |
DefaultNumberOfReplicas |
1 |
默认副本数 |
表达式字段选择(推荐)
所有接受 string field / string[] fields 参数的搜索方法都提供了 表达式重载,通过 x => x.PropertyName 自动解析 ES 字段名,避免手写字符串出错:
// ❌ 字符串方式(容易拼错、重构不友好)
await _es.FullTextSearchAsync<Product>("手机", ["name", "description"]);
await _es.TermSearchAsync<Product>("category", "手机");
await _es.SuggestAsync<Product>("华为", "suggest");
// ✅ 表达式方式(编译时检查、自动解析 [ElasticField] 特性的 FieldName)
await _es.FullTextSearchAsync<Product>("手机", [x => x.Name, x => x.Description]);
await _es.TermSearchAsync<Product>(x => x.Category, "手机");
await _es.SuggestAsync<Product>("华为", x => x.Suggest);
支持表达式的方法:FullTextSearchAsync、SearchPagedAsync、TermSearchAsync、HighlightSearchAsync、SuggestAsync、SuggestMultiFieldAsync、WildcardSearchAsync、PrefixSearchAsync、UpdateFieldsAsync、TermsAggregationAsync。
也可以直接使用 ElasticFieldResolver 手动解析:
var fieldName = ElasticFieldResolver.Resolve<Product>(x => x.Name); // "name" 或 [ElasticField(FieldName = "xxx")] 的值
var fieldNames = ElasticFieldResolver.ResolveMany<Product>(x => x.Name, x => x.Description);
索引管理
| 方法 | 说明 |
|---|---|
IndexExistsAsync |
判断索引是否存在 |
CreateIndexAsync<T> |
根据特性自动创建索引 + 字段映射 + 设置 |
EnsureIndexAsync<T> |
索引不存在则自动创建 |
DeleteIndexAsync |
删除索引 |
UpdateIndexMappingAsync<T> |
更新索引映射(仅可新增字段,不可修改已有字段类型) |
UpdateIndexSettingsAsync |
动态更新索引设置(副本数、刷新间隔、结果窗口等) |
UpdateIndexSettingsAsync<T> |
根据 [ElasticsearchIndex] 特性更新动态设置 |
RefreshIndexAsync |
强制刷新索引(使写入对搜索可见) |
ReindexAsync |
将数据从源索引迁移到目标索引 |
CloseIndexAsync |
关闭索引(修改静态设置前需关闭) |
OpenIndexAsync |
打开索引(恢复读写) |
AddAliasAsync |
为索引添加别名 |
RemoveAliasAsync |
移除索引别名 |
GetAliasesAsync |
获取索引的所有别名 |
IndexSettingsBuilder
通过 UpdateIndexSettingsAsync 使用流式构建器更新动态设置:
await _es.UpdateIndexSettingsAsync("products", settings => settings
.NumberOfReplicas(2) // 副本数
.RefreshInterval("30s") // 刷新间隔("-1" 禁用自动刷新)
.MaxResultWindow(50000) // from + size 上限
.MaxRescoreWindow(10000) // 最大重评分窗口
.Set("index.gc_deletes", "60s") // 自定义设置
);
零停机索引迁移(Reindex + Alias)
// 1. 创建新索引(新映射/新设置)
await _es.CreateIndexAsync<ProductV2>("products_v2");
// 2. 迁移数据
var count = await _es.ReindexAsync("products", "products_v2");
// 3. 切换别名(零停机)
await _es.RemoveAliasAsync("products", "products_live");
await _es.AddAliasAsync("products_v2", "products_live");
// 4. 删除旧索引
await _es.DeleteIndexAsync("products");
项目结构
GaoXinLibrary.ElasticSearch/
├── Attributes/ # 特性标注
│ ├── ElasticCompletionAttribute.cs # Completion 子字段特性
│ ├── ElasticFieldAttribute.cs # 字段映射特性
│ └── ElasticsearchIndexAttribute.cs # 索引配置特性
├── Builders/ # 构建器
│ ├── ElasticSearchBuilder.cs # 搜索构建器(Bool 查询 + 排序 + 高亮 + 分页)
│ └── IndexSettingsBuilder.cs # 索引设置构建器
├── Core/ # 核心基础设施
│ ├── ElasticsearchClientFactory.cs # 客户端工厂(内部单例)
│ ├── ElasticsearchOptions.cs # 连接配置选项
│ └── ElasticFieldResolver.cs # 表达式字段解析器
├── Enums/ # 枚举类型
│ ├── AnalyzerType.cs # 分析器类型
│ └── ElasticFieldType.cs # 字段映射类型
├── Extensions/ # DI 扩展
│ └── ServiceCollectionExtensions.cs # AddElasticsearch() 注册
├── Models/ # 返回结果模型
│ ├── PagedSearchResult.cs # 分页搜索结果
│ ├── SearchResult.cs # 搜索结果(含高亮)
│ └── SuggestResult.cs # 自动补全结果
└── Services/ # 服务接口与实现
├── IElasticsearchService.cs # 服务接口
└── ElasticsearchService.cs # 服务实现
前提条件
- Elasticsearch 9.x 集群
- 如需 IK 分词,需安装 elasticsearch-analysis-ik 插件
License
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Elastic.Clients.Elasticsearch (>= 9.3.2)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.5)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.5)
- Microsoft.Extensions.Options (>= 10.0.5)
-
net8.0
- Elastic.Clients.Elasticsearch (>= 9.3.2)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.3)
- Microsoft.Extensions.Options (>= 8.0.2)
-
net9.0
- Elastic.Clients.Elasticsearch (>= 9.3.2)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.14)
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.14)
- Microsoft.Extensions.Options (>= 9.0.14)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.1 | 111 | 3/13/2026 |
| 1.0.0-beta.2 | 68 | 3/10/2026 |