- 本系列已經所有完成,完整版可見 :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 | 使用聚合