1. 程式人生 > >net core 2.x - 日誌 - to elasticsearch - (2)

net core 2.x - 日誌 - to elasticsearch - (2)

你可能會有疑惑,怎麼又來一偏,,,其實我也好奇,因為我已經忘記哪個能跑起來了,,,記憶中,這個好像是沒問題的.

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

 

 

 

下班.