net core 2.x
你可能會有疑惑,怎麼又來一偏,,,其實我也好奇,因為我已經忘記哪個能跑起來了,,,記憶中,這個好像是沒問題的.
1.使用到的資源
關於es(elasticseach)在.net中的訪問,可以參考es的官網,有很明確的說明了可以使用elasticsearch.net和nest, 需要詳細瞭解的 點這裡 (走你>>>) 進入之後點選introduction既可看到這倆個東西的介紹.所以首先我們先nuget install一下,這裡我們使用的是nest.
install-package nest
2.使用及配置參考
2.1 程式碼及配置參考
為了更方便和更靈活的使用,我們需要稍微處理下,配置參考如下(配置檔案中):
{ "Logging": { "LogLevel": { "Default": "Warning" } }, "ElasticSearch": { "Uri": "http://localhost:9200/", "DefaultIndex": "default-", "UserName": null, "Password": null }, "AllowedHosts": "*" }
這裡我們添加了一個 ElasticSearch節點,裡面的就是我們的es的配置資訊了,然後新建一個對應的 類物件,方便我們直接訪問,這裡我們起名叫 ESOptions.cs
/// <summary> /// ES配置 選項 /// </summary> public class ESOptions { public string Uri { get; set; } public string DefaultIndex { get; set; } public string UserName { get; set; } public string Password { get; set; } }
到這裡你可能就知道下面要幹嘛了,是的,就是要獲取配置引數,如下圖:
這裡直接將配置引數物件 通過IOptions<>注入到了需要使用的類中,這裡是有前提的,需要我們在startup.cs的configureServices方法中先配置,所以配置中加入一行:
services.Configure<ESOptions>(Configuration.GetSection("ElasticSearch"));
這樣就可以直接使用IOptions<>注入並獲取配置物件啦.完整實現程式碼如下,這裡我們新建一個類:名稱為:ESClientProvider.cs
public class ESClientProvider<T> where T : class { public ESClientProvider(IOptions<ESOptions> options) { var settings = new ConnectionSettings(new Uri(options.Value.Uri)) .DefaultIndex(options.Value.DefaultIndex); if (!String.IsNullOrEmpty(options.Value.UserName) && !String.IsNullOrEmpty(options.Value.Password)) { settings.BasicAuthentication(options.Value.UserName, options.Value.Password); } this.Client = new ElasticClient(settings); this.DefaultIndex = options.Value.DefaultIndex; EnsureIndexWithMapping(this.DefaultIndex); } public ElasticClient Client { get; private set; } public string DefaultIndex { get; set; } public void EnsureIndexWithMapping(string indexName = null, Func<PutMappingDescriptor<T>, PutMappingDescriptor<T>> customMapping = null) { if (String.IsNullOrEmpty(indexName)) indexName = this.DefaultIndex; // Map type T to that index this.Client.ConnectionSettings.DefaultIndices.Add(typeof(T), indexName); // Does the index exists? var indexExistsResponse = this.Client.IndexExists(new IndexExistsRequest(indexName)); if (!indexExistsResponse.IsValid) throw new InvalidOperationException(indexExistsResponse.DebugInformation); // If exists, return if (indexExistsResponse.Exists) return; // Otherwise create the index and the type mapping var createIndexRes = this.Client.CreateIndex(indexName); if (!createIndexRes.IsValid) throw new InvalidOperationException(createIndexRes.DebugInformation); var res = this.Client.Map<T>(m => { m.AutoMap().Index(indexName); if (customMapping != null) m = customMapping(m); return m; }); if (!res.IsValid) throw new InvalidOperationException(res.DebugInformation); } }
這裡需要使用到的名稱空間就是我們開始說的 using nest;另外我們這裡還多了一個方法 EnsureIndexWithMapping 看名字就明白了,可就是確保index存在對映關係,這是什麼意思?矇蔽了吧?腦瓜子嗡嗡的了吧.....淡定,這裡的這個index指的是 es物件的index,如果還有不瞭解es的相關概念的可以看我之前的隨筆 (走起>>>),這個mapping也即是建立Index時候建立的mapping對映.其中還有兩個引數 Client,這個物件,是提供給使用這個類的物件,直接通過 Client 這個屬性直接訪問 Nest中的相關方法,比如:Client.IndexDocumentAsync,Client.SearchAsync 等等.;另一個屬性 DefaultIndex就是提供的預設的索引的名稱.這樣我們的基礎工作基本完成了,這時候看我們的目錄,其實就兩個檔案(我單獨放置在一個standard)中:
這時候我們只需要在startup.cs中配置一下就好啦,將我們的這個ESClient{rovider.cs的類注入到容器中:
2.2 使用參考
首先在我們的控制器中注入物件:
public ArdLoggerController(ESClientProvider<LogViewModel> eSClientProvider) { _esClientProvider = eSClientProvider; } private ESClientProvider<LogViewModel> _esClientProvider;
使用參考:
public async Task<IActionResult> Create([FromBody] LogViewModel model) { var res = await _esClientProvider.Client.IndexDocumentAsync<LogViewModel>(model); if (!res.IsValid) { throw new InvalidOperationException(res.DebugInformation); } return Ok(); }
public async Task<IActionResult> Query(string keywords, int? pageIndex = 0, int? pageSize = 10) { var searchResponse = await _esClientProvider.Client.SearchAsync<LogViewModel>( s => s .From(pageIndex) .Size(pageSize) .Query(q => q .Match(m => m .Field(f => f .AreaKeyWords ) .Analyzer(keywords) ) ) ); var logInfo = searchResponse.Documents; return Ok(logInfo); }
下班.