1. 程式人生 > >elasticsearch.net search入門使用指南中文版(翻譯)

elasticsearch.net search入門使用指南中文版(翻譯)

per set option 數量 允許 工具 hapi bsp smart

elasticsearch.net search入門使用指南中文版,elasticsearch.Net是一個非常底層且靈活的客戶端,它不在意你如何的構建自己的請求和響應。它非常抽象,因此所有的elasticsearchAPI被表示為方法,沒

elasticsearch.net search入門使用指南中文版

elasticsearch.net為什麽會有兩個客戶端?

Elasticsearch.Net是一個非常底層且靈活的客戶端,它不在意你如何的構建自己的請求和響應。它非常抽象,因此所有的Elasticsearch API被表示為方法,沒有太多關於你想如何構建json/request/response對象的東東,並且它還內置了可配置、可重寫的集群故障轉移機制。

Elasticsearch.Net有非常大的彈性,如果你想更好的提升你的搜索服務,你完全可以使用它來做為你的客戶端。

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

NEST Client

elasticsearch.net(NEST)客戶端提供了強類型查詢DSL,方便用戶使用,源碼下載。

一、如何安裝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; }
}
//懶人建站http://www.51xuediannao.com/

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

屬性名值類型描述
Analyzer string 分析器名稱,值包含standard、simple、whitespace、stop、keyward、pattern、language、snowball、custom等,查看分析器更多信息請點擊Elasticsearch Analyzers
Boost double 加權值,值越大得分越高
NullValue string 插入文檔時,如果數據為NULL時的默認值
Index FieldIndexOption 是否使用分析器,默認使用FieldIndexOption.Analyzed,禁止使用分析器FieldIndexOption.NotAnalyzed

2、NumberAttribute

屬性名值類型描述
type NumberType 構造函數參數,指定當前屬性的類型,NumberType.Default、Float、Double、Integer、Long、Short、Byte
Boost double 加權值,值越大得分越高
NullValue double 插入文檔時,如果數據為NULL時的默認值

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,並且作者不等於“俏佳人”的文檔

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("俏佳人"))
        )
    )
);
//c#教程http://www.51xuediannao.com/c_asp_net/

註意:

如果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、過濾作者等於“歷史小河”的文檔

query.PostFilter(x => x.Term(t => t.Field(obj => obj.Author).Value("歷史小河")));

4、過濾作者等於“歷史小河”或者等於“友誼的小船”的文檔,匹配多個作者中間用空格隔開

query.PostFilter(x => x.QueryString(t => t.Fields(f => f.Field(obj => obj.Author)).Query("歷史小河 友誼的小船")));

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 = "江山美人" }));

局部更新批量文檔

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 = "胡一刀" };

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

原文:http://edu.dmeiyang.com/book/nestusing.html

elasticsearch.net search入門使用指南中文版(翻譯)