NEST 之旅 · 開啓

NEST 之旅 · 開啓

Version:5.xhtml

英文原文地址:Getting startedc#

說實話,這篇文章翻譯的很糟糕。可是個人能力有限,目前只有這個水平,還望各位多指導。api

NEST 是 Elasticsearch 的一個高層級的 .NET 客戶端,可是它仍然很是接近原始的 Elasticsearch API 。NEST 中全部的請求和響應都是經過類型公開的,這使得它能夠快速地啓動和運行。服務器

在美麗的外表之下,NEST 有着一個強大的低層級的核心 - Elasticsearch.Net 。有了這個核心,NEST 才得以(向 Elasticsearch 本體服務程序)發送請求和接收響應。這個過程當中,NEST 使用和擴展了 Elasticsearch.NET 的許多類型。另外,NEST 公開了這個低級客戶端,你能夠經過 .LowLevel 屬性來訪問。異步

Connecting

鏈接位於 http://localhost:9200 的本地 Elasticsearch 是很是簡單的,你只須要實例化一個客戶端的實例便可。async

var client = new ElasticClient();

一般狀況下,你會須要向客戶端傳遞一些額外的配置選項。好比:你的 Elasticsearch 在遠程服務器上運行,那你就須要傳遞它的具體地址。 ConnectionSettings 參數就是來接收這些配置信息的,有了它你就能夠根據不一樣的配置實例化出相應的客戶端。elasticsearch

var settings = new ConnectionSettings(new Uri("http://example.com:9200"))
    .DefaultIndex("people");

var client = new ElasticClient(settings);

仔細看上面這個例子,咱們設置了一個默認索引。若是請求中沒有明確提供其餘索引,而且沒法從 POCO 泛型參數中推斷出索引,就會使用這個默認索引。ConnectionSettings 繼承自 ConnnectionConfiguraion ,Elasticsearch.NET (那個低層級的客戶端)經過這個對象來接收額外的配置選項。瞭解更多的配置選項,請訪問 Configuration optionside

注意,若是沒有配置默認索引,而 NEST 又沒法從請求中推斷出索引,那它就會拋出一個異常。函數

ConnectionSettings 沒有嚴格要求只能向 Elasticsearch 傳遞一個地址。NEST 中還提供了幾種不一樣類型的鏈接池用來配置客戶端。下面的栗子使用了一個 SniffingConnectionPool ,它包含了集羣中 3 個 Elasticsearch 節點的地址。客戶端將使用這種鏈接池來維護一個集羣中可用節點的列表,這樣即可以用循環的方式發送請求。佈局

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");

var client = new ElasticClient(settings);

Indexing

將客戶端配置好並鏈接上 Elasticsearch 以後,咱們須要往集羣裏存儲一些數據。

假設咱們有以下簡單傳統CLR對象(Plain Old CLR Object)

public class Person
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

使用同步或者異步的方式索引一個 POCO 實例

var person = new Person
{
    Id = 1,
    FirstName = "Martijn",
    LastName = "Laarman"
};

var indexResponse = client.Index(person); (1)

var asyncIndexResponse = await client.IndexAsync(person); (2)

(1) 同步方法返回一個 IIndexResponse 對象

(2) 異步方法返回一個可等待的 Task<IIndexResponse> 對象

注意:NEST 中全部的方法都提供了同步和異步兩種版本,異步方法使用 *Async 後綴命名

上述代碼會將文檔索引到 /people/person/1 。NEST 很聰明,它會根據 Person 的 CLR 類型來推斷 type ,並根據 POCO 的 Id 屬性來推斷文檔的 id 。瞭解 NEST 中推斷文檔 id 的其餘方式,請參閱 Ids inferenceConnectionSettings 中配置的默認索引會被用來看成請求的索引名。

警告:NEST 會將 POCO 序列化爲 JSON 文檔發送給 Elasticsearch。默認狀況下,在執行序列化時,NEST 將 POCO 的屬性名轉換成駝峯式字符串。你可使用 ConnectionSettings.DefaultFieldNameInferrer(Func<string,string>) 方法來改變這一行爲。

Searching

咱們已經索引了一些文檔,接下來就能夠開始查詢了。

var searchResponse = client.Search<Person>(s => s
    .From(0)
    .Size(10)
    .Query(q => q
         .Match(m => m
            .Field(f => f.FirstName)
            .Query("Martijn")
         )
    )
);

var people = searchResponse.Documents;

people 變量如今保存着名字裏包含 Martijn 的前十我的的文檔。這個查詢的搜索終端是 /people/person/_search ,其中索引名由 ConnectionSettings 中的默認索引肯定,類型名由搜索時傳遞的泛型參數 Person 肯定。

使用 .AllTypes() 能夠搜索索引內的所有類型

var searchResponse = client.Search<Person>(s => s
    .AllTypes()
    .From(0)
    .Size(10)
    .Query(q => q
         .Match(m => m
            .Field(f => f.FirstName)
            .Query("Martijn")
         )
    )
);

請求中能夠提供單個或者多個索引和類型名,瞭解更多請分別參閱 Indices pathsDocument paths

到目前爲止,全部的搜索示例都使用了 NEST 的 Fluent API ,它使用 lambda 表達式構造結構化的查詢,這一點模仿了 Elasticsearch 中的 Query DSL 的查詢結構。

NEST 還公開了一個對象初始值設定語法,對於那些不熱衷於深層嵌套子表達式的開發者,能夠用這種方式來構造查詢(佈局是關鍵 ~)

這裏有個和以前的栗子相同的查詢,不過改爲了使用對象初始值設定語法來構造查詢

var searchRequest = new SearchRequest<Person>(Nest.Indices.All, Types.All) (1)
{
    From = 0,
    Size = 10,
    Query = new MatchQuery
    {
        Field = Infer.Field<Person>(f => f.FirstName),
        Query = "Martijn"
    }
};

var searchResponse = await client.SearchAsync<Person>(searchRequest);

(1) 全部的索引和類型,都在構造函數中指定

筆記:本文開始的時候提到過,高層客戶端經過 .LowLevel 屬性公開了 Elasticsearch.NET 的低層客戶端。有些狀況下,低層客戶端會更合適。例如:你已經有了一個 JSON 對象,想直接發送給服務器,而不但願再把它轉換成 Fluent API 或者 Object Initializer 語法。又或者說,高層客戶端有一個 bug,讓你不得不選擇低層客戶端。使用低層客戶端,能夠經過發送字符串或者匿名類型的請求來完成工做。

經過 .LowLevel 來使用低層客戶端,你可使用 NEST 中全部的強類型和序列化功能

這裏有個示例:

var searchResponse = client.LowLevel.Search<SearchResponse<Person>>("people", "person", new
{
    from = 0,
    size = 10,
    query = new
    {
        match = new
        {
            field = "firstName",
            query = "Martijn"
        }
    }
});

var responseJson = searchResponse.Body;

能夠看到,請求是一個匿名類型,可是響應體是 NEST 返回的響應類型的具體實現。

Aggregations

除告終構化和非結構化的查詢,Elasticsearch 還支持聚合數據

var searchResponse = await client.SearchAsync<Person>(s => s
    .Size(0)
    .Query(q => q
         .Match(m => m
            .Field(f => f.FirstName)
            .Query("Martijn")
         )
    )
    .Aggregations(a => a
        .Terms("last_names", ta => ta
            .Field(f => f.LastName)
        )
    )
);

var termsAggregation = searchResponse.Aggs.Terms("last_names");

這個例子裏,match 查詢搜索出了名字裏有 "Martijn" 的人,這和以前的例子是同樣的,不一樣的是:

  1. 將 size 設爲 0 ,由於咱們不須要查到的前 10 份文檔,咱們只對聚合結果感興趣
  2. 指定了一個 terms 聚合,從而將搜索結果按照姓氏分組

termsAggregation 能夠用於獲取每一個桶的文檔數量,其中每一個桶的鍵是姓氏。更多信息,請參閱 Writing aggregations

相關文章
相關標籤/搜索