你可能会有疑惑,怎么又来一偏,,,其实我也好奇,因为我已经忘记哪个能跑起来了,,,记忆中,这个好像是没问题的.
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); }
下班.