C# 如何使用 Elasticsearch (ES)

來源:互聯網
上載者:User

標籤:互動   處理   概念   cts   tno   免費   stat   搜尋   分詞   

 

Elasticsearch簡介

 

Elasticsearch (ES)是一個基於Apache Lucene(TM)的開源搜尋引擎,無論在開源還是專有領域,Lucene可以被認為是迄今為止最先進、效能最好的、功能最全的搜尋引擎庫。 

 

但是,Lucene只是一個庫。想要發揮其強大的作用,你需使用C#將其整合到你的應用中。Lucene非常複雜,你需要深入的瞭解檢索相關知識來理解它是如何工作的。 

 

Elasticsearch是使用Java編寫並使用Lucene來建立索引並實現搜尋功能,但是它的目的是通過簡單連貫的RESTful API讓全文檢索搜尋變得簡單並隱藏Lucene的複雜性。 

 

不過,Elasticsearch不僅僅是Lucene和全文檢索搜尋引擎,它還提供:

 

  • 分布式的即時檔案儲存體,每個欄位都被索引並可被搜尋

     

  • 即時分析的分布式搜尋引擎

     

  • 可以擴充到上百台伺服器,處理PB級結構化或非結構化資料

 

而且,所有的這些功能被整合到一台伺服器,你的應用可以通過簡單的RESTful API、各種語言的用戶端甚至命令列與之互動。

 

上手Elasticsearch非常簡單,它提供了許多合理的預設值,並對初學者隱藏了複雜的搜尋引擎理論。它開箱即用(安裝即可使用),只需很少的學習既可在生產環境中使用。Elasticsearch在Apache 2 license下許可使用,可以免費下載、使用和修改。 

 

隨著知識的積累,你可以根據不同的問題領域定製Elasticsearch的進階特性,這一切都是可配置的,並且配置非常靈活。

 

以上內容來自 [百度百科] 

 

關於ES詳細概念見:

 

http://88250.b3log.org/full-text-search-elasticsearch#b3_solo_h3_0

 

使用C#操作ES

 

NEST是一個高層的用戶端,可以映射所有請求和響應對象,擁有一個強型別查詢DSL(領特定領域語言),並且可以使用.net的特性比如協變、Auto Mapping Of POCOs,NEST內部使用的依然是Elasticsearch.Net用戶端。

 

Elasticsearch.net(NEST)用戶端提供了強型別查詢DSL,方便使用者使用,源碼下載。(https://github.com/elastic/elasticsearch-net/releases/tag/2.4.4)

 

一、如何安裝NEST

 

開啟VS的工具菜單,通過NuGet包管理器控制台,輸入以下命令安裝NEST

 

Install-Package NEST

 

安裝後引用了以下三個DLL

 

  • Elasticsearch.Net.dll(2.4.4)

     

  • Nest.dll(2.4.4)

     

  • Newtonsoft.Json.dll(9.0版本)

 

二、連結elasticsearch

 

你可以通過單個節點或者指定多個節點使用串連池連結到Elasticsearch叢集,使用串連池要比單個節點連結到Elasticsearch更有優勢,比如支援負載平衡、容錯移轉等。

 

通過單點連結:

 

var node = new Uri("http://myserver:9200");

var settings = new ConnectionSettings(node);

var client = new ElasticClient(settings);

 

通過串連池連結:

 

var nodes = new Uri[]

{

    new Uri("http://myserver1:9200"),

    new Uri("http://myserver2:9200"),

    new Uri("http://myserver3:9200")

};

var pool = new StaticConnectionPool(nodes);

var settings = new ConnectionSettings(pool);

var client = new ElasticClient(settings);

 

NEST Index

 

為了知道請求需要操作哪個索引,Elasticsearch API期望收到一個或多個索引名稱作為請求的一部分。

 

一、指定索引

 

1、可以通過ConnectionSettings使用.DefaultIndex(),來指定預設索引。當一個請求裡沒有指定具體索引時,NEST將請求預設索引。

 

var settings = new ConnectionSettings()

    .DefaultIndex("defaultindex");

 

2、可以通過ConnectionSettings使用.MapDefaultTypeIndices(),來指定被映射為CLR類型的索引。

 

var settings = new ConnectionSettings()

    .MapDefaultTypeIndices(m => m

        .Add(typeof(Project), "projects")

    );

 

注意:通過.MapDefaultTypeIndices()指定索引的優先順序要高於通過.DefaultIndex()指定索引,並且更適合簡單對象(POCO)

 

3、另外還可以顯示的為請求指定索引名稱,例如:

 

var response = client.Index(student, s=>s.Index("db_test"));

var result = client.Search<Student>(s => s.Index("db_test"));

var result = client.Delete<Student>(null, s => s.Index("db_test"));

……

 

注意:當現實的為請求指定索引名稱時,這個優先順序是最高的,高於以上兩種方式指定的索引。

 

4、一些Elasticsearch API(比如query)可以採用一個、多個索引名稱或者使用_all特殊標誌發送請求,請求NEST上的多個或者所有節點

 

//請求單一節點

var singleString = Nest.Indices.Index("db_studnet");

var singleTyped = Nest.Indices.Index<Student>();

 

ISearchRequest singleStringRequest = new SearchDescriptor<Student>().Index(singleString);

ISearchRequest singleTypedRequest = new SearchDescriptor<Student>().Index(singleTyped);

 

//請求多個節點

var manyStrings = Nest.Indices.Index("db_studnet", "db_other_student");

var manyTypes = Nest.Indices.Index<Student>().And<OtherStudent>();

 

ISearchRequest manyStringRequest = new SearchDescriptor<Student>().Index(manyStrings);

ISearchRequest manyTypedRequest = new SearchDescriptor<Student>().Index(manyTypes);

 

//請求所有節點

var indicesAll = Nest.Indices.All;

var allIndices = Nest.Indices.AllIndices;

 

ISearchRequest indicesAllRequest = new SearchDescriptor<Student>().Index(indicesAll);

ISearchRequest allIndicesRequest = new SearchDescriptor<Student>().Index(allIndices);

 

二、建立索引

 

Elasticsearch API允許你建立索引的同時對索引進行配置,例如:

 

var descriptor = new CreateIndexDescriptor("db_student")

    .Settings(s => s.NumberOfShards(5).NumberOfReplicas(1));

client.CreateIndex(descriptor);

 

這裡指定了該索引的分區數為5、副本數為1。

 

三、刪除索引

 

Elasticsearch API允許你刪除索引,例如:

 

var descriptor = new DeleteIndexDescriptor("db_student").Index("db_student");

client.DeleteIndex(descriptor)

 

這裡制定了要刪除的索引名稱“db_student”,以下為更多刪除用例:

 

 //刪除指定索引所在節點下的所有索引

 var descriptor = new DeleteIndexDescriptor("db_student").AllIndices();

 

NEST Mapping

 

NEST提供了多種映射方法,這裡介紹下通過Attribute自訂映射。

 

一、簡單實現

 

1、定義業務需要的POCO,並指定需要的Attribute

 

[ElasticsearchType(Name = "student")]

public class Student

{

    [Nest.String(Index = FieldIndexOption.NotAnalyzed)]

    public string Id { get; set; }

    [Nest.String(Analyzer = "standard")]

    public string Name { get; set; }

    [Nest.String(Analyzer = "standard")]

    public string Description { get; set; }

    public DateTime DateTime { get; set; }

}

 

2、接著我們通過.AutoMap()來實現映射

 

var descriptor = new CreateIndexDescriptor("db_student")

    .Settings(s => s.NumberOfShards(5).NumberOfReplicas(1))

    .Mappings(ms => ms

        .Map<Student>(m => m.AutoMap())

    );

client.CreateIndex(descriptor);

 

注意:通過.Properties()可以重寫通過Attribute定義的映射

 

二、Attribute介紹

 

1、StringAttribute

 

 

2、NumberAttribute

 

 

3、BooleanAttribute

 

屬性名稱 實值型別 描述
Boost double 加權值,值越大得分越高
NullValue double 插入文檔時,如果資料為NULL時的預設值

 

4、DateAttribute

 

屬性名稱 實值型別 描述
Boost double 加權值,值越大得分越高
NullValue string 插入文檔時,如果資料為NULL時的預設值
Format string  

 

5、ObjectAttribute

 

屬性名稱 實值型別 描述
type string/Type 建構函式參數,指定當前屬性的類型T
Dynamic DynamicMapping  

 

NEST Search

 

NEST提供了支援Lambda鏈式query DLS(領特定領域語言)方式,以下是簡單實現及各個query的簡述。

 

一、簡單實現

 

1、定義SearchDescriptor,方便項目中複雜業務的實現

 

var query = new Nest.SearchDescriptor<Models.ESObject>();

var result = client.Search<Student>(x => query)

 

2、檢索title和content中包含key,並且作者不等於“wenli”的文檔

 

query.Query(q =>

    q.Bool(b =>

        b.Must(m =>

            m.MultiMatch(t => t.Fields(f => f.Field(obj => obj.Title).Field(obj => obj.Content)).Query(key))

        )

        .MustNot(m =>

            m.QueryString(t => t.Fields(f => f.Field(obj => obj.Author)).Query("wenli"))

        )

    )

);

 

注意:

 

如果Elasticsearch使用預設分詞,Title和Content的attribute為[Nest.String(Analyzer = "standard")]

 

如果Elasticsearch使用的是IK分詞,Title和Content的attribute為[Nest.String(Analyzer = "ikmaxword")]或者[Nest.String(Analyzer = "ik_smart")]

 

Author的attribute為[Nest.String(Index = FieldIndexOption.NotAnalyzed)],禁止流量分析器

 

3、過濾作者等於“wenli”的文檔

 

query.PostFilter(x => x.Term(t => t.Field(obj => obj.Author).Value("wenli")));

 

4、過濾作者等於“wenli”或者等於“yswenli”的文檔,匹配多個作者中間用空格隔開

 

query.PostFilter(x => x.QueryString(t => t.Fields(f => f.Field(obj => obj.Author)).Query("wenli yswenli")));

 

5、過濾數量在1~100之間的文檔

 

query.PostFilter(x => x.Range(t => t.Field(obj => obj.Number).GreaterThanOrEquals(1).LessThanOrEquals(100)));

 

6、排序,按照得分倒敘排列

 

query.Sort(x => x.Field("_score", Nest.SortOrder.Descending));

 

7、定義高亮樣式及欄位

 

query.Highlight(h => h

    .PreTags("<b>")

    .PostTags("</b>")

    .Fields(

        f => f.Field(obj => obj.Title),

        f => f.Field(obj => obj.Content),

        f => f.Field("_all")

    )

);

 

8、拼裝查詢內容,整理資料,方便前段調用

 

var list = result.Hits.Select(c => new Models.ESObject()

{

    Id = c.Source.Id,

    Title = c.Highlights == null ? c.Source.Title : c.Highlights.Keys.Contains("title") ? string.Join("", c.Highlights["title"].Highlights) : c.Source.Title, //高亮顯示的內容,一條記錄中出現了幾次

    Content = c.Highlights == null ? c.Source.Content : c.Highlights.Keys.Contains("content") ? string.Join("", c.Highlights["content"].Highlights) : c.Source.Content, //高亮顯示的內容,一條記錄中出現了幾次

    Author = c.Source.Author,

    Number = c.Source.Number,

    IsDisplay = c.Source.IsDisplay,

    Tags = c.Source.Tags,

    Comments = c.Source.Comments,

    DateTime = c.Source.DateTime,

})

 

二、query DSL介紹 

 

elasticsearch.net Document

 

文檔操作包含添加/更新文檔、局部更新文檔、刪除文檔及對應的大量操作文檔方法。

 

一、添加/更新文檔及大量操作

 

添加/更新單一文檔

 

Client.Index(student);

 

大量新增/更新文檔

 

var list = new List<Student>();

client.IndexMany<Student>(list);

 

二、局部更新單一文檔及大量操作

 

局部更新單一文檔

 

client.Update<Student, object>("002", upt => upt.Doc(new { Name = "wenli" }));

 

局部更新批量文檔

 

var ids = new List<string>() { "002" };

var bulkQuest = new BulkRequest() { Operations = new List<IBulkOperation>() };

foreach (var v in ids)

{

    var operation = new BulkUpdateOperation<Student, object>(v);

    operation.Doc = new { Name = "wenli" };

    bulkQuest.Operations.Add(operation);

}

var result = client.Bulk(bulkQuest);

 

三、刪除文檔及大量操作

 

刪除單一文檔

 

client.Delete<Student>("001");

 

大量刪除文檔

 

var ids = new List<string>() { "001", "002" };

var bulkQuest = new BulkRequest() { Operations = new List<IBulkOperation>() };

foreach (var v in ids)

{

    bulkQuest.Operations.Add(new BulkDeleteOperation<Student>(v));

}

var result = client.Bulk(bulkQuest);

 

轉至: cnblogs.com/yswenli/p/6266569.html

C# 如何使用 Elasticsearch (ES)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.