1. 初识Elasticsearch与NEST
Elasticsearch作为分布式搜索和分析引擎,在处理海量数据时表现优异。而NEST作为其官方.NET客户端,就像给C#开发者配了把瑞士军刀。通过对象映射机制,它能把C#的类自动转换成ES文档,配合强类型API设计,让代码可读性飙升。
这里有个冷知识:NEST的查询构建器支持链式调用,这种设计让代码看起来像在说人话。比如Query(q => q.MatchAll())
这种写法,是不是比裸写JSON舒服多了?
2. 环境准备
(.NET 6 + NEST 7.17.5) 先装个NuGet包:
Install-Package NEST -Version 7.17.5
创建连接客户端:
var settings = new ConnectionSettings(new Uri("http://localhost:9200"))
.DefaultIndex("products"); // 设置默认索引
var client = new ElasticClient(settings);
3. 排序的小策略
3.1 基础排序
var searchResponse = await client.SearchAsync<Product>(s => s
.Query(q => q.MatchAll())
.Sort(srt => srt
.Descending(p => p.Price) // 按价格降序
.Ascending(p => p.CreateTime) // 按创建时间升序
)
);
// 结果处理示例
foreach (var hit in searchResponse.Hits)
{
Console.WriteLine($"{hit.Source.Name} 价格:{hit.Source.Price}");
}
3.2 距离排序(地理坐标)
var searchResponse = await client.SearchAsync<Store>(s => s
.Query(q => q
.GeoDistance(g => g
.Field(f => f.Location)
.Distance("2km")
.Location(31.2304, 121.4737) // 上海坐标
)
)
.Sort(srt => srt
.GeoDistance(g => g
.Field(f => f.Location)
.Order(SortOrder.Ascending)
.Unit(DistanceUnit.Kilometers)
.Points(new GeoCoordinate(31.2304, 121.4737))
)
)
);
4. 过滤的艺术
4.1 精确值过滤
var response = client.Search<Product>(s => s
.Query(q => q
.Term(t => t
.Field(f => f.Category.Suffix("keyword")) // 使用keyword类型字段
.Value("电子产品")
)
)
);
4.2 范围过滤
var response = client.Search<Product>(s => s
.Query(q => q
.Range(r => r
.Field(f => f.Price)
.GreaterThanOrEqualTo(1000)
.LessThan(5000)
)
)
);
4.3 组合过滤
var response = client.Search<Product>(s => s
.Query(q => q
.Bool(b => b
.Must(
q => q.Term(t => t.Category, "电子产品"),
q => q.Range(r => r.Price >= 1000)
)
.MustNot(q => q
.Term(t => t.StockQuantity, 0)
)
)
)
);
5. 关联技术:索引映射管理
创建带keyword类型的索引:
var createIndexResponse = client.Indices.Create("products", c => c
.Map<Product>(m => m
.Properties(p => p
.Keyword(k => k.Name(n => n.Category))
.Number(n => n.Name(n => n.Price).Type(NumberType.Double))
.Date(d => d.Name(n => n.CreateTime))
)
)
);
6. 应用场景剖析
- 电商平台:商品价格区间过滤+销量排序
- 物流系统:按距离排序最近的仓库
- 日志分析:错误日志的等级过滤+时间排序
- 社交应用:好友动态的时间轴排序
7. 技术优缺点对比
优势:
- 强类型API避免手写JSON的错误
- LINQ风格的查询构建更符合C#习惯
- 自动处理连接池和重试机制
- 丰富的聚合功能支持
不足:
- 学习曲线比直接使用REST API陡峭
- 版本更新可能导致API变更
- 复杂查询的性能需要调优
8. 避坑指南
- 注意字段类型:text类型字段不能直接排序
- 分页陷阱:避免使用from+size处理大数据集
- 映射管理:提前规划字段的索引策略
- 版本兼容:确保NEST和ES版本匹配
- 异常处理:捕获ElasticsearchClientException
9. 最佳实践总结
- 使用
_source
参数控制返回字段 - 为经常过滤的字段添加keyword类型
- 合理使用
Explain()
调试查询 - 定期更新映射时使用别名切换
- 监控慢查询日志优化性能