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

 

 

 

下班.

 

posted @ 2018-11-21 16:42  esoftor  阅读(761)  评论(1编辑  收藏  举报