.Net Core中使用ElasticSearch(二)

  .Net的ElasticSearch 有兩個版本,Elasticsearch.Net(低級) 和 NEST(高級),推薦使用 NEST,低級版本的更靈活,水太深 把握不住。有個需要注意,使用的版本號必須要ElasticSearch服務端版本號一致。

一、 連接池

  1.1 SingleNodeConnectionPool 單節點連接池

    適合只有一個節點的情況。當沒有在ConnectionSettings 構造函數中顯式指定連接池類型的時候,默認此連接池。這種連接池不會標記節點是否存活

  1.2 StaticConnectionPool 靜態連接池

    適合多個節點,它維護一個靜態的節點hosts清單,使用前通過ping節點來確認節點是否存活。如果一個節點處理請求失敗,該節點會被標記爲死節點,這個節點會被“關禁閉”,“關禁閉”出來後,會再次處理請求,如果還是失敗,“關禁閉”的時間會更長。

  1.3 SniffingConnectionPool 嗅探連接池

    它繼承至靜態連接池,有靜態連接池的Ping特性。區別在於是動態的,用戶提供hosts種子,而客戶端則會嗅探這些hosts並發現集羣的其他節點。當集羣中添加或刪除節點時,客戶端會相應更新。

  1.4 StickyConnectionPool 黏性連接池

    選擇一個可用節點作爲請求主節點,支持ping 不支持嗅探

  1.5 StickySniffingConnectionPool 黏性嗅探連接池

    選擇一個可用節點作爲請求主節點,支持ping 支持嗅探

二、注入

   官方推薦使用單例注入ElasticClient。

            services.AddSingleton<IElasticClient>(provider =>
            {
                var connectionPool = new SingleNodeConnectionPool(new Uri("http://127.0.0.1:9200"));
                var connectionSetting = new ConnectionSettings(connectionPool).DisableDirectStreaming();
                return new ElasticClient(connectionSetting);
            });              

三、增刪改查

3.1 添加

3.1.1 單個添加

var user = new User()
{
    Id = 1,
    Age = 18,
    Name = "MicroHeart",
    Gender = true
};
//第一種
var resp = client.Index(user, s => s.Index(indexName));//指定操作索引名稱 //第二種 connectionSettings.DefaultIndex(indexName);//指定默認索引名稱 var client = new ElasticClient(connectionSettings); resp = client.IndexDocument(user);//操作默認索引

3.1.2 批量添加

//第一種
var resp = client.IndexMany(new List<User>() { user }); //操作默認索引
resp = client.IndexMany(new List<User>() { user }, indexName); //操作指定索引
//第二種
resp = client.Bulk(b => b.Index(indexName).IndexMany(users, (desc, user) => desc.Index(user.Gender ? "boy" : "girl")));
//第三種
var bulkAllObservable = client.BulkAll(users, b => b
                            .Index("people")
                            .BackOffTime("30s") //重試間隔時間
                            .BackOffRetries(2)  //重試次數
                            .RefreshOnCompleted()
                            .MaxDegreeOfParallelism(Environment.ProcessorCount)
                            .Size(1000) //每次請求文檔個數
                        );

IndexMany:是在單個 HTTP 請求所有文檔,因此對於非常大的文檔集合,這不是建議的方法。

Bulk:是在單個 HTTP 請求所有文檔,如果需要對很多文檔進行索引控制,可以使用此方法。例子中將男孩插入“boy”索引中,女孩添加到“girl”索引中

BulkAll:適合對多個大文檔集合操作,在多個HTTP請求中,分批次操作文檔,內置了重試機制。

上面所有的插入方法都是根據_id的值判斷文檔是否存在(這裏因爲user有個屬性爲Id,默認Es將Id的屬性值作爲_id的值),如果已經存在文檔,就更新,否則就添加。

通過返回對象的IsValid屬性來判斷是否添加成功。

 

3.2 刪除

var resp = client.Delete<User>(1, d => d.Index(indexName));//單個刪除
var resp = client.DeleteByQuery<User>(x => x.Index(indexName).Query(q => q.Range(r => r.Field(f => f.Age).LessThan(18)))); //刪除年齡小於18的

返回的對象包含

deleted:表示刪除的數量。 

Failures:刪除失敗的集合。

 

3.3 查詢

3.3.1 根據Id獲取單個

var resp = client.Get<User>(3, d => d.Index(indexName));

返回的類型爲 GetResponse<User>,包含下面幾個屬性。

index:表示索引,

type:值固定爲“_doc”,

found:表示是否找到文檔,

version:文檔的版本號,

source:存儲的數據user

 

3.3.2 根據Id集合獲取多個

 var resp = client.GetMany<User>(new List<long>() { 19L, 20L, 21L }, indexName);

3.3.3 根據條件查詢

var resp = client.Search<User>(x => x.Index(indexName)
                                     .From(0)
                                     .Size(20)
                                     .Query(q => q.Range(r => r.Field(f => f.Age).GreaterThan(18)) &&
                                                 q.Range(r => r.Field(f => f.Age).LessThan(30)) &&
                                                 q.Term(t => t.Gender, true)));

返回的類型爲 ISearchResponse<User>,包含下面幾個屬性。

TimedOut:查詢是否超時

Shards:完成這個搜索查詢了多少個分片

Took:此次查詢消耗的時間

MaxScore:此次查詢中最符合查詢條件的文檔的最大得分

Total:符合查詢條件的總數

Hits:存儲的數據user集合

例子只是簡單的查詢。ES專爲查詢而生,所以它的查詢很靈活,後面單獨講。

 

 3.4 更新

var user = new User()
{
    Age = 18,
    Gender = false,
    Name = "test"
};
var resp4 = client.Update<User>(20, u => u.Index(indexName).Doc(user));

 返回的IsValid 表示是否更新成功。

 

 封裝裝一個操作倉儲,鏈接

 

   

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章