- 本系列已经所有完成,完整版可见 :https://blog.zhuliang.ltd/categories/Elasticsearch/
- 本系列博文是“伪”官方文档翻译(更加本土化),并不是彻底将官方文档进行翻译,而是在查阅、测试原始文档并转换为本身真知灼见后的“准”翻译。有不一样看法 / 说明不周的地方,还请海涵、不吝拍砖 :)
- 官方文档见此:https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/introduction.html
- 本系列对应的版本环境:ElasticSearch@7.3.1,NEST@7.3.1,IDE 和开发平台默认为 VS2019,.NET CORE 2.1
Elasticsearch.Net 和 NEST 对比说明:html
基本上 .NET 项目到了要使用上 ElasticSearch 的地步,直接选择 NEST 便可。api
在使用 NEST 做为客户端的时候,建议将 ElasticClient 对象做为单例来使用。缓存
- 使用 Nest 的时候约定 Nest 版本须要跟 ElasticSearch 版本保持一致,即服务端 ES版本为 7.3.1,则 Nest 版本也要使用 7.3.1
- 如下示例经过 IoC 进行注入(单例),你也能够直接经过单例模式来实现。
配置类:安全
public class ElasticSearchSettings { public string ServerUri { get; set; } public string DefaultIndex { get; set; } = "defaultindex"; }
ElasticSearch 客户端:异步
public class ElasticSearchClient : IElasticSearchRepository { private readonly ElasticSearchSettings _esSettings; private readonly ElasticClient _client; public ElasticSearchClient(IOptions<ElasticSearchSettings> esSettings) { _esSettings = esSettings.Value; var settings = new ConnectionSettings(new Uri(_esSettings.ServerUri)).DefaultIndex(_esSettings.DefaultIndex); _client = new ElasticClient(settings); } public ElasticSearchClient(ElasticSearchSettings esSettings) { _esSettings = esSettings; var settings = new ConnectionSettings(new Uri(_esSettings.ServerUri)).DefaultIndex(_esSettings.DefaultIndex); _client = new ElasticClient(settings); } }
ElasticSearch 能够直接在 Uri 上指定密码,以下:elasticsearch
var uri = new Uri("http://username:password@localhost:9200") var settings = new ConnectionConfiguration(uri);
ConnectionSettings 不只支持单地址的链接方式,一样提供了不一样类型的链接池来让你配置客户端,如使用 SniffingConnectionPool 来链接集群中的 3 个 Elasticsearch 节点,客户端将使用该类型的链接池来维护集群中的可用节点列表,并会以循环的方式发送调用请求。ide
var uris = new[]{ new Uri("http://localhost:9200"), new Uri("http://localhost:9201"), new Uri("http://localhost:9202"),}; var connectionPool = new SniffingConnectionPool(uris);var settings = new ConnectionSettings(connectionPool) .DefaultIndex("people"); _client = new ElasticClient(settings);
NEST 教程系列 2-1 链接:Configuration options| 配置选项测试
假设有以下类 User.csui
public class User { public Guid Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } }
索引(Indexing)/添加 一份文档到 ES 中.net
//同步 var response = _client.IndexDocument<User>(new User { Id = new Guid("3a351ea1-bfc3-43df-ae12-9c89e22af144"), FirstName = "f1", LastName = "l1" }); //异步 var response = _client.IndexDocumentAsync<User>(new User { Id = new Guid("82f323e3-b5ec-486b-ac88-1bc5e47ec643"), FirstName = "f2", LastName = "l2" });
最终请求地址为:
PUT /users/_doc/3a351ea1-bfc3-43df-ae12-9c89e22af144
经过 Search
var result = _client.Search<User>(s=>s.From(0) .Size(10) .Query(q=>q.Match(m=>m.Field(f=>f.LastName).Query("l1"))));
请求 URL 以下:
POST /users/_search?typed_keys=true
如何在 ES 上的全部索引上进行搜索?经过 AllIndices(),以下:
var result = _client.Search<User>(s=>s .AllIndices() //指定在全部索引上进行查询 .From(0) .Size(10) .Query(q=>q.Match(m=>m.Field(f=>f.LastName).Query("l1"))));
假设有以下文档:
//users 索引 "hits" : [ { "_index" : "users", "_type" : "_doc", "_id" : "3a351ea1-bfc3-43df-ae12-9c89e22af144", "_score" : 1.0, "_source" : { "id" : "3a351ea1-bfc3-43df-ae12-9c89e22af144", "firstName" : "f1", "lastName" : "l1" } }, { "_index" : "users", "_type" : "_doc", "_id" : "05245504-053c-431a-984f-23e16d8fbbc9", "_score" : 1.0, "_source" : { "id" : "05245504-053c-431a-984f-23e16d8fbbc9", "firstName" : "f2", "lastName" : "l2" } } ] // thirdusers 索引 "hits" : [ { "_index" : "thirdusers", "_type" : "_doc", "_id" : "619ad5f8-c918-46ef-82a8-82a724ca5443", "_score" : 1.0, "_source" : { "firstName" : "f1", "lastName" : "l1" } } ]
则最终能够获取到 users 和 thirdusers 索引中分别获取到 _id 为 3a351ea1-bfc3-43df-ae12-9c89e22af144 和 619ad5f8-c918-46ef-82a8-82a724ca5443 的文档信息。
能够经过 .AllTypes() 和 .AllIndices() 从全部 类型(types) 和 全部 索引(index)中查询数据,最终查询会生成在 /_search 请求中。关于 Type 和 Index,可分别参考:NEST 教程系列 9-6 转换:Document Paths 文档路径和跳转:NEST 教程系列 9-7 转换:Indices Paths 索引路径
经过 SearchRequest 对象进行查询。
例:在全部索引查询 LastName="l1"的文档信息
var request = new SearchRequest(Nest.Indices.All) //在全部索引上查询 { From = 0, Size = 10, Query = new MatchQuery { Field = Infer.Field<User>(f => f.LastName), Query = "l1" } }; var response = _client.Search<User>(request);
生成的请求 URL 为:
POST /_all/_search?typed_keys=true
使用 Elasticsearch.Net 来进行查询的契机:
var response = _client.LowLevel.Search<SearchResponse<User>>("users", PostData.Serializable(new { from = 0, size = 10, query = new { match = new { lastName = "l1" } } }));
除告终构化和非结构化查询以外, ES 一样支持聚合(Aggregations)查询:
var result = _client.Search<User>(s => s .Size(0) //设置为 0 ,可让结果只包含聚合的部分:即 hits 属性中没有结果,聚合结果显示在 ”aggregations“ .Query(q => q.Match(m => m.Field(f => f.FirstName) .Query("f2"))) .Aggregations(a => //使用 terms 聚合,并指定到桶 last_name 中 a.Terms("last_name", ta => ta.Field(f => f.LastName))) );
更多关于聚合的操做可见此:NEST 教程系列 8 聚合:Writing aggregations | 使用聚合