zoukankan      html  css  js  c++  java
  • C# Elasticsearch帮助类

    ElasticsearchConfig

     /// <summary>
        /// ES 连接配置
        /// </summary>
        public class ElasticsearchConfig
        {
            /// <summary>
            /// 节点列表
            /// </summary>
            public IEnumerable<ElasticsearchNode> Nodes { get; set; }
    
            /// <summary>
            /// 连接池类型
            /// </summary>
            public ElasticsearchConnectionPoolType PoolType { get; set; } = ElasticsearchConnectionPoolType.Static;
    
            /// <summary>
            /// 用户名
            /// </summary>
            public string UserName { get; set; }
    
            /// <summary>
            /// 密码
            /// </summary>
            public string Password { get; set; }
    
            /// <summary>
            /// 显示调试信息
            /// </summary>
            public bool DisableDebugInfo { get; set; } = true;
    
            /// <summary>
            /// 抛出异常。默认false,错误信息在每个操作的response中
            /// </summary>
            public bool ThrowExceptions { get; set; } = false;
    
            /// <summary>
            /// 是否禁用Ping。禁用ping 第一次使用节点或使用被标记死亡的节点进行ping
            /// </summary>
            public bool DisablePing { get; set; } = true;
        }
    

      ElasticsearchConfigProvider

     /// <summary>
        /// Elasticsearch 配置提供程序
        /// </summary>
        public class ElasticsearchConfigProvider : IElasticsearchConfigProvider
        {
            /// <summary>
            /// 配置
            /// </summary>
            private readonly ElasticsearchConfig _config;
    
            /// <summary>
            /// 初始化一个<see cref="ElasticsearchConfigProvider"/>类型的实例
            /// </summary>
            /// <param name="config">Elasticsearch 连接配置</param>
            public ElasticsearchConfigProvider(ElasticsearchConfig config)
            {
                _config = config;
            }
    
            /// <summary>
            /// 获取配置
            /// </summary>
            /// <returns></returns>
            public Task<ElasticsearchConfig> GetConfigAsync()
            {
                return Task.FromResult(_config);
            }
        }
    

      ElasticsearchConnectionPoolType

     /// <summary>
        /// ES 连接池类型。
        /// 支持ping-说明能够发现节点的状态;
        /// 支持嗅探-说明能够发现新的节点
        /// </summary>
        public enum ElasticsearchConnectionPoolType
        {
            /// <summary>
            /// 静态连接池。推荐使用,应用于已知集群,请求时随机请求各个正常节点,支持ping,不支持嗅探
            /// </summary>
            Static,
            /// <summary>
            /// 单节点连接池
            /// </summary>
            SingleNode,
            /// <summary>
            /// 嗅探连接池。可动态嗅探集群,随机请求,支持嗅探、ping
            /// </summary>
            Sniffing,
            /// <summary>
            /// 固定连接池。选择一个可用节点作为请求主节点,支持ping,不支持嗅探
            /// </summary>
            Sticky,
            /// <summary>
            /// 固定嗅探连接池。选择一个可用节点作为请求主节点,支持ping,支持嗅探
            /// </summary>
            StickySniffing
        }
    

      ElasticsearchNode

    /// <summary>
        /// Elasticsearch 节点
        /// </summary>
        public class ElasticsearchNode
        {
            /// <summary>
            /// 主机
            /// </summary>
            public string Host { get; set; }
    
            /// <summary>
            /// 端口号
            /// </summary>
            public uint Port { get; set; }
    
            /// <summary>
            /// 输出字符串
            /// </summary>
            /// <returns></returns>
            public override string ToString()
            {
                var port = Port == 0 ? "" : $":{Port}";
    
                var result = $"{Host}{port}".ToLowerInvariant();
                return result.IndexOf("http", StringComparison.OrdinalIgnoreCase) > -1 ? result : $"http://{result}";
            }
        }
    

      IElasticsearchConfigProvider

     public interface IElasticsearchConfigProvider
        {
            /// <summary>
            /// 获取配置
            /// </summary>
            /// <returns></returns>
            Task<ElasticsearchConfig> GetConfigAsync();
        }
    

      ElasticClientExtensions

    /// <summary>
        /// ES客户端(<see cref="IElasticClient"/>) 扩展
        /// </summary>
        internal static class ElasticClientExtensions
        {
            /// <summary>
            /// 初始化索引映射
            /// </summary>
            /// <param name="client">ES客户端</param>
            /// <param name="indexName">索引名</param>
            public static async Task InitializeIndexMapAsync(this IElasticClient client, string indexName)
            {
                var newName = indexName + DateTime.Now.Ticks;
                var result = await client.CreateIndexAsync(newName,
                    t => t.Index(newName).Settings(x => x.NumberOfShards(1).NumberOfReplicas(1).Setting("max_result_window", int.MaxValue)));
    
                if (result.Acknowledged)
                {
                    await client.AliasAsync(x => x.Add(o => o.Index(newName).Alias(indexName)));
                    return;
                }
                throw new ElasticsearchException($"创建索引 {indexName} 失败:{result.ServerError.Error.Reason}");
            }
    
            /// <summary>
            /// 初始化索引映射
            /// </summary>
            /// <typeparam name="T">实体类型</typeparam>
            /// <param name="client">ES客户端</param>
            /// <param name="indexName">索引名</param>
            public static async Task InitializeIndexMapAsync<T>(this IElasticClient client, string indexName) where T : class
            {
                var newName = indexName + DateTime.Now.Ticks;
                var result = await client.CreateIndexAsync(newName,
                    t => t.Index(newName)
                    .Settings(o => o.NumberOfShards(1).NumberOfReplicas(1)
                    .Setting("max_result_window", int.MaxValue))
                    .Mappings(m => m.Map<T>(mm => mm.AutoMap())));
                if (result.Acknowledged)
                {
                    await client.AliasAsync(x => x.Add(o => o.Index(newName).Alias(indexName)));
                    return;
                }
                throw new ElasticsearchException($"创建索引 {indexName} 失败:{result.ServerError.Error.Reason}");
            }
    
            /// <summary>
            /// 初始化索引映射
            /// </summary>
            /// <typeparam name="T">实体类型</typeparam>
            /// <param name="client">ES客户端</param>
            /// <param name="indexName">索引名</param>
            public static async Task InitializeIndexMapAsync<T>(this IElasticClient client, string indexName, int numberOfShards,
               int numberOfReplicas) where T : class
            {
                var newName = indexName + DateTime.Now.Ticks;
                var result = await client.CreateIndexAsync(newName,
                    x => x.Index(newName)
                        .Settings(o =>
                            o.NumberOfShards(numberOfShards)
                                .NumberOfReplicas(numberOfReplicas)
                                .Setting("max_result_window", int.MaxValue))
                        .Mappings(m => m.Map<T>(mm => mm.AutoMap())));
                if (result.Acknowledged)
                {
                    await client.AliasAsync(x => x.Add(o => o.Index(newName).Alias(indexName)));
                    return;
                }
                throw new ElasticsearchException($"创建索引 {indexName} 失败:{result.ServerError.Error.Reason}");
            }
    
        }
    

      HighlightParam

     public class HighlightParam
        {
            /// <summary>
            /// 高亮字段
            /// </summary>
            public string[] Keys { get; set; }
    
            /// <summary>
            /// 高亮标签
            /// </summary>
            public string PreTags { get; set; } = "<em>";
    
            /// <summary>
            /// 高亮标签
            /// </summary>
            public string PostTags { get; set; } = "</em>";
    
            /// <summary>
            /// 高亮字段前缀。
            /// 例如:title 高亮值赋值给 h_title
            /// </summary>
            public string PrefixOfKey { get; set; } = string.Empty;
    
            /// <summary>
            /// 是否替换原来的值
            /// </summary>
            public bool ReplaceAuto { get; set; } = true;
        }
    

      IPageParam

     public interface IPageParam
        {
            /// <summary>
            /// 页数,即第几页,从1开始
            /// </summary>
            int Page { get; set; }
    
            /// <summary>
            /// 每页显示行数
            /// </summary>
            int PageSize { get; set; }
    
            /// <summary>
            /// 关键词
            /// </summary>
            string Keyword { get; set; }
    
            /// <summary>
            /// 获取跳过的行数
            /// </summary>
            /// <returns></returns>
            int GetSkipCount();
    
            /// <summary>
            /// 运算符
            /// </summary>
            Nest.Operator Operator { get; set; }
    
            /// <summary>
            /// 高亮参数
            /// </summary>
            HighlightParam Highlight { get; set; }
        }
    
        /// <summary>
        /// 分页参数
        /// </summary>
        public class PageParam : IPageParam
        {
            /// <summary>
            /// 页数,即第几页,从1开始
            /// </summary>
            public int Page { get; set; }
    
            /// <summary>
            /// 每页显示行数
            /// </summary>
            public int PageSize { get; set; }
    
            /// <summary>
            /// 关键词
            /// </summary>
            public string Keyword { get; set; }
    
            /// <summary>
            /// 获取跳过的行数
            /// </summary>
            /// <returns></returns>
            public int GetSkipCount() => (Page - 1) * PageSize;
    
            /// <summary>
            /// 运算符
            /// </summary>
            public Nest.Operator Operator { get; set; } = Nest.Operator.And;
    
            /// <summary>
            /// 高亮参数
            /// </summary>
            public HighlightParam Highlight { get; set; }
        }
    
        /// <summary>
        /// 指定字段查询
        /// </summary>
        public class PageParamWithSearch : PageParam
        {
            /// <summary>
            /// 查询字段列表
            /// </summary>
            public string[] SearchKeys { get; set; }
        }
    

      IQueryResult

    /// <summary>
        /// 查询结果
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        public interface IQueryResult<T>
        {
            /// <summary>
            /// 总行数
            /// </summary>
            long TotalCount { get; set; }
    
            /// <summary>
            /// 查询占用时间
            /// </summary>
            long Took { get; set; }
    
            /// <summary>
            /// 数据
            /// </summary>
            IEnumerable<T> Data { get; }
        }
    
        /// <summary>
        /// 自定义查询结果
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        public class CustomQueryResult<T> : IQueryResult<T>
        {
            /// <summary>
            /// 总行数
            /// </summary>
            public long TotalCount { get; set; }
    
            /// <summary>
            /// 查询占用时间
            /// </summary>
            public long Took { get; set; }
    
            /// <summary>
            /// 数据
            /// </summary>
            public IEnumerable<T> Data { get; set; }
        }
    

      ElasticsearchClient

    /// <summary>
        /// ES客户端
        /// </summary>
        public class ElasticsearchClient : IElasticsearchClient
        {
            /// <summary>
            /// ES客户端生成器
            /// </summary>
            private ElasticsearchClientBuilder _builder;
    
            /// <summary>
            /// 配置提供程序
            /// </summary>
            private IElasticsearchConfigProvider _configProvider;
    
            /// <summary>
            /// 初始化一个<see cref="ElasticsearchClient"/>类型的实例
            /// </summary>
            /// <param name="configProvider">配置提供程序</param>
            public ElasticsearchClient(IElasticsearchConfigProvider configProvider)
            {
                _configProvider = configProvider ?? throw new ArgumentNullException(nameof(configProvider));
                _builder = new ElasticsearchClientBuilder(configProvider);
            }
    
            /// <summary>
            /// 是否存在指定索引
            /// </summary>
            /// <param name="indexName">索引名</param>
            /// <returns></returns>
            public async Task<bool> ExistsAsync(string indexName)
            {
                var client = await _builder.GetClientAsync();
                var result = await client.IndexExistsAsync(indexName);
                return result.Exists;
            }
    
            /// <summary>
            /// 添加索引。不映射
            /// </summary>
            /// <param name="indexName">索引名</param>
            public async Task AddAsync(string indexName)
            {
                var client = await _builder.GetClientAsync();
                if (await ExistsAsync(indexName)) return;
                await client.InitializeIndexMapAsync(indexName);
            }
    
            /// <summary>
            /// 添加索引。自动映射实体属性
            /// </summary>
            /// <typeparam name="T">实体类型</typeparam>
            /// <param name="indexName">索引名</param>
            public async Task AddAsync<T>(string indexName) where T : class
            {
                var client = await _builder.GetClientAsync();
                if (await ExistsAsync(indexName)) return;
    
                await client.InitializeIndexMapAsync<T>(indexName);
            }
    
            /// <summary>
            /// 添加索引。自动映射实体属性并赋值
            /// </summary>
            /// <typeparam name="T">实体类型</typeparam>
            /// <param name="indexName">索引名</param>
            /// <param name="entity">实体</param>
            public async Task AddAsync<T>(string indexName, T entity) where T : class
            {
                var client = await _builder.GetClientAsync();
                if (!await ExistsAsync(indexName))
                    await client.InitializeIndexMapAsync<T>(indexName);
    
                var response = await client.IndexAsync(entity, x => x.Index(indexName));
                if(!response.IsValid)
                    throw new ElasticsearchException($"新增数据[{indexName}]失败 : {response.ServerError.Error.Reason}");
            }
    
            /// <summary>
            /// 更新索引。
            /// 由于是普通的简单更新,当ID已经存在时,则会更新文档,所以这里直接调用index方法(复杂方法待研究)
            /// </summary>
            /// <typeparam name="T">实体类型</typeparam>
            /// <param name="indexName">索引名</param>
            /// <param name="entity">实体</param>
            public async Task UpdateAsync<T>(string indexName, T entity) where T : class
                =>await AddAsync<T>(indexName, entity);
    
            /// <summary>
            /// 删除索引
            /// </summary>
            /// <param name="indexName">索引名</param>
            public async Task DeleteAsync(string indexName)
            {
                var client = await _builder.GetClientAsync();
                var response = await client.DeleteIndexAsync(indexName);
    
                if (response.Acknowledged) return;
            }
    
            /// <summary>
            /// 删除索引
            /// </summary>
            /// <typeparam name="T">实体类型</typeparam>
            /// <param name="indexName">索引名</param>
            /// <param name="entity">实体</param>
            public async Task DeleteAsync<T>(string indexName, T entity) where T : class
            {
                var client = await _builder.GetClientAsync();
                var response = await client.DeleteAsync(new DeleteRequest(indexName, typeof(T), new Id(entity)));
                if (response.ServerError == null) return;
    
                throw new ElasticsearchException($"删除索引[{indexName}]失败 : {response.ServerError.Error.Reason}");
            }
    
            /// <summary>
            /// 删除索引
            /// </summary>
            /// <typeparam name="T">实体类型</typeparam>
            /// <param name="indexName">索引名</param>
            /// <param name="id">主键ID</param>
            public async Task DeleteAsync<T>(string indexName, long id) where T : class
            {
                var client = await _builder.GetClientAsync();
                var response = await client.DeleteAsync(DocumentPath<T>.Id(new Id(id)), x => x.Type<T>().Index(indexName));
    
                if (response.ServerError == null) return;
    
                throw new ElasticsearchException($"删除索引[{indexName}]失败 : {response.ServerError.Error.Reason}");
            }
    
            /// <summary>
            /// 查询实体
            /// </summary>
            /// <typeparam name="T">实体类型</typeparam>
            /// <param name="indexName">索引名</param>
            /// <param name="id">主键ID</param>
            /// <returns></returns>
            public async Task<T> FindAsync<T>(string indexName, long id) where T : class
            {
                var client = await _builder.GetClientAsync();
                var response = await client.GetAsync<T>(id, x => x.Type<T>().Index(indexName));
                return response?.Source;
            }
    
            /// <summary>
            /// 查询。单一条件查询,一般是精确查询
            /// </summary>
            /// <typeparam name="T">实体类型</typeparam>
            /// <param name="indexName">索引名</param>
            /// <param name="field">字段名</param>
            /// <param name="value">查询值</param>
            /// <returns></returns>
            public async Task<IEnumerable<T>> QueryAsync<T>(string indexName, string field, object value) where T : class
            {
                if (string.IsNullOrWhiteSpace(field))
                    return null;
    
                var client = await _builder.GetClientAsync();
                var searchRequest = new SearchDescriptor<T>()
                    .Index(indexName)
                    .PostFilter(t => t.Term(x => x.Field(field).Value(value)));
                var response = await client.SearchAsync<T>(searchRequest);
                return response.Documents;
            }
    
            /// <summary>
            /// 查找实体列表
            /// </summary>
            /// <typeparam name="T">实体类型</typeparam>
            /// <param name="indexName">索引名</param>
            /// <param name="ids">主键值</param>
            /// <returns></returns>
            public async Task<IEnumerable<T>> FindByIdsAsync<T>(string indexName, params long[] ids) where T : class
            {
                var client = await _builder.GetClientAsync();
                var searchRequest = new SearchDescriptor<T>().Index(indexName).Query(t => t.Ids(x => x.Values(ids)));
                var response = await client.SearchAsync<T>(searchRequest);
                return response.Documents;
            }
    
            /// <summary>
            /// 查找实体列表
            /// </summary>
            /// <typeparam name="T">实体类型</typeparam>
            /// <param name="indexName">索引名</param>
            /// <param name="ids">主键值</param>
            /// <returns></returns>
            public async Task<IEnumerable<T>> FindByIdsAsync<T>(string indexName, params string[] ids) where T : class
            {
                var client = await _builder.GetClientAsync();
                var searchRequest = new SearchDescriptor<T>().Index(indexName).Query(t => t.Ids(x => x.Values(ids)));
                var response = await client.SearchAsync<T>(searchRequest);
                return response.Documents;
            }
    
            /// <summary>
            /// 查找实体列表
            /// </summary>
            /// <typeparam name="T">实体类型</typeparam>
            /// <param name="indexName">索引名</param>
            /// <param name="ids">主键值</param>
            /// <returns></returns>
            public async Task<IEnumerable<T>> FindByIdsAsync<T>(string indexName, params Guid[] ids) where T : class
            {
                var client = await _builder.GetClientAsync();
                var searchRequest = new SearchDescriptor<T>().Index(indexName).Query(q => q.Ids(x => x.Values(ids)));
                var response = await client.SearchAsync<T>(searchRequest);
                return response.Documents;
            }
    
            /// <summary>
            /// 分页查询
            /// </summary>
            /// <typeparam name="T">实体类型</typeparam>
            /// <param name="param">分页参数</param>
            /// <param name="indexName">索引名</param>
            /// <returns></returns>
            public async Task<IQueryResult<T>> PageQueryAsync<T>(IPageParam param, string indexName) where T : class
            {
                if (param == null)
                {
                    param = new PageParam()
                    {
                        Page = 1,
                        PageSize = 20
                    };
                }
    
                var searchRequest = new SearchDescriptor<T>()
                    .Type<T>()
                    .Index(indexName)
                    .From(param.GetSkipCount())
                     .Size(param.PageSize);
    
                if (param is PageParamWithSearch pageSearch)
                    ConfigPageRequest(pageSearch, ref searchRequest);
                else if(param is PageParam pageParam)
                    ConfigPageRequest(pageParam, ref searchRequest);
    
                // 是否需要高亮
                bool hasHighlight = param.Highlight?.Keys?.Length > 0;
                if(hasHighlight)
                    BuildHighLightQuery(param, ref searchRequest);
    
                var client = await _builder.GetClientAsync();
                var response = await client.SearchAsync<T>(x => searchRequest);
    
                //if (hasHighlight)
                //{
                //    var listWithHightlight = new List<T>();
                //    response.Hits.ToList().ForEach(x =>
                //    {
                //        if (x.Highlights?.Count > 0)
                //        {
                //            PropertyInfo[] properties = typeof(T).GetProperties();
                //            foreach (string key in pageParams.Highlight?.Keys)
                //            {
                //                //先得到要替换的内容
                //                if (x.Highlights.ContainsKey(key))
                //                {
                //                    string value = string.Join("", x.Highlights[key]?.Highlights);
                //                    PropertyInfo info = properties.FirstOrDefault(p => p.Name == pageParams.Highlight.PrefixOfKey + key);
                //                    //没找到带前缀的属性,则替换之前的
                //                    if (info == null && pageParams.Highlight.ReplaceAuto)
                //                    {
                //                        info = properties.FirstOrDefault(p => p.Name == key);
                //                    }
                //                    if (info?.CanWrite == true)
                //                    {
                //                        if (!string.IsNullOrEmpty(value))
                //                        {
                //                            //如果高亮字段不为空,才赋值,否则就赋值成空
                //                            info.SetValue(x.Source, value);
                //                        }
                //                    }
                //                }
                //            }
                //        }
                //        listWithHightlight.Add(x.Source);
                //    });
                //}
    
                return new CustomQueryResult<T>()
                {
                    Data = response.Documents,
                    Took = response.Took,
                    TotalCount = response.Total
                };
            }
    
            /// <summary>
            /// 配置指定字段的分页请求
            /// </summary>
            private void ConfigPageRequest<T>(PageParamWithSearch param, ref SearchDescriptor<T> searchRequest) where T : class
            {
                searchRequest = searchRequest.Query(t=>
                  t.QueryString(x =>
                        x.Fields(param.SearchKeys)
                            .Query(param.Keyword)
                            .DefaultOperator(param.Operator)));
            }
    
            /// <summary>
            /// 配置分页请求
            /// </summary>
            private void ConfigPageRequest<T>(PageParam param, ref SearchDescriptor<T> searchRequest) where T : class
            {
                searchRequest= searchRequest.Query(
                    t=>t.QueryString(q=>q.Query(param.Keyword)
                .DefaultOperator(param.Operator)));
            }
    
            /// <summary>
            /// 构造高亮查询
            /// </summary>
            private void BuildHighLightQuery<T>(IPageParam param, ref SearchDescriptor<T> searchRequest) where T : class
            {
                var keysLength = param.Highlight?.Keys?.Length ?? 0;
                var fieldDescriptor = new Func<HighlightFieldDescriptor<T>, IHighlightField>[keysLength];
                var keysIndex = 0;
    
                foreach (var key in param.Highlight?.Keys)
                {
                    fieldDescriptor[keysIndex] = hf => hf.Field(key)
                        .HighlightQuery(q => q.Match(m => m.Field(key).Query(param.Keyword)));
                    keysIndex++;
                }
    
                IHighlight highlight = new HighlightDescriptor<T>()
                   .PreTags(param.Highlight.PreTags)
                   .PostTags(param.Highlight.PostTags)
                   .Fields(fieldDescriptor);
                searchRequest = searchRequest.Highlight(s => highlight);
            }
    
            /// <summary>
            /// 批量保存
            /// </summary>
            /// <typeparam name="T">实体类型</typeparam>
            /// <param name="indexName">索引名</param>
            /// <param name="entities">实体列表</param>
            public async Task BulkSaveAsync<T>(string indexName, IEnumerable<T> entities) where T : class
            {
                var client = await _builder.GetClientAsync();
    
                if (!await ExistsAsync(indexName))
                {
                    await client.InitializeIndexMapAsync<T>(indexName);
                }
                var bulk = new BulkRequest(indexName)
                {
                    Operations = new List<IBulkOperation>()
                };
                foreach (var entity in entities)
                {
                    bulk.Operations.Add(new BulkIndexOperation<T>(entity));
                }
    
                var response = await client.BulkAsync(bulk);
                if (response.Errors)
                {
                    throw new ElasticsearchException($"批量保存文档在索引 {indexName} 失败:{response.ServerError.Error.Reason}");
                }
            }
        }
    

      ElasticsearchClientBuilder

    /// <summary>
        /// ES客户端生成器
        /// </summary>
        internal class ElasticsearchClientBuilder
        {
            /// <summary>
            /// ES客户端
            /// </summary>
            private IElasticClient _client;
    
            /// <summary>
            /// 配置提供程序
            /// </summary>
            private readonly IElasticsearchConfigProvider _configProvider;
    
            /// <summary>
            /// 对象锁
            /// </summary>
            private static object _lock = new object();
    
            /// <summary>
            /// 初始化一个<see cref="ElasticsearchClientBuilder"/>类型的实例
            /// </summary>
            /// <param name="configProvider">配置提供程序</param>
            public ElasticsearchClientBuilder(IElasticsearchConfigProvider configProvider)
            {
                _configProvider = configProvider;
            }
    
            /// <summary>
            /// 获取ES客户端
            /// </summary>
            /// <returns></returns>
            public async Task<IElasticClient> GetClientAsync()
            {
                if (_client == null)
                {
                    var config = await _configProvider.GetConfigAsync();
                    lock (_lock)
                    {
                        if (_client == null)
                        {
                            if (config.Nodes == null) throw new ArgumentException("请设置ES客户端节点");
    
                            _client = CreateClient(config);
                        }
                    }
                }
    
                return _client;
            }
    
            /// <summary>
            /// 创建ES客户端
            /// </summary>
            /// <param name="config">配置</param>
            /// <returns></returns>
            private IElasticClient CreateClient(ElasticsearchConfig config)
            {
                var connectionPool = CreateConnectionPool(config);
                var settings = new ConnectionSettings(connectionPool);
                ConfigSettings(settings, config);
                return new ElasticClient(settings);
            }
    
            /// <summary>
            /// 创建连接池
            /// </summary>
            /// <param name="config"></param>
            /// <returns></returns>
            private IConnectionPool CreateConnectionPool(ElasticsearchConfig config)
            {
                var nodes = config.Nodes.Select(t => new Uri(t.ToString())).ToList();
                switch (config.PoolType)
                {
                    case ElasticsearchConnectionPoolType.Static:
                        return new StaticConnectionPool(nodes);
                    case ElasticsearchConnectionPoolType.SingleNode:
                        return new SingleNodeConnectionPool(nodes.FirstOrDefault());
                    case ElasticsearchConnectionPoolType.Sniffing:
                        return new SniffingConnectionPool(nodes);
                    case ElasticsearchConnectionPoolType.Sticky:
                        return new StickyConnectionPool(nodes);
                    case ElasticsearchConnectionPoolType.StickySniffing:
                        return new StickySniffingConnectionPool(nodes, x => 1.0F);
                    default:
                        return new StaticConnectionPool(nodes);
                }
            }
    
            /// <summary>
            /// 配置连接设置
            /// </summary>
            /// <param name="settings">连接设置</param>
            /// <param name="config">配置</param>
            private void ConfigSettings(ConnectionSettings settings, ElasticsearchConfig config)
            {
                // 启用验证
                if (!string.IsNullOrWhiteSpace(config.UserName) && !string.IsNullOrWhiteSpace(config.Password))
                    settings.BasicAuthentication(config.UserName, config.Password);
    
                // 验证证书
                //settings.ClientCertificate("");
                //settings.ClientCertificates(new System.Security.Cryptography.X509Certificates.X509CertificateCollection());
                //settings.ServerCertificateValidationCallback();
    
                // 开启第一次使用时进行嗅探,需连接池支持
                //settings.SniffOnStartup(false);
    
                // 链接最大并发数
                //settings.ConnectionLimit(80);
    
                // 标记为死亡节点的超时时间
                //settings.DeadTimeout(new TimeSpan(10000));
                //settings.MaxDeadTimeout(new TimeSpan(10000));
    
                // 最大重试次数
                //settings.MaximumRetries(5);
    
                // 重试超时时间,默认是RequestTimeout
                //settings.MaxRetryTimeout(new TimeSpan(50000));
    
                // 禁用代理自动检测
                //settings.DisableAutomaticProxyDetection(true);
    
                // 禁用ping,第一次使用节点或使用被标记死亡的节点进行ping
                settings.DisablePing(config.DisablePing);
    
                // ping超时设置
                //settings.PingTimeout(new TimeSpan(10000));
    
                // 选择节点
                //settings.NodePredicate(node => { return true; });
    
                // 默认操作索引
                //settings.DefaultIndex("");
    
                // 字段名规则 与model字段同名
                //settings.DefaultFieldNameInferrer(name => name);
    
                // 根据Type获取类型名
                //settings.DefaultTypeNameInferrer(name => name.Name);
    
                // 请求超时设置
                //settings.RequestTimeout(new TimeSpan(10000));
    
                // 调试信息
                settings.DisableDirectStreaming(config.DisableDebugInfo);
                //settings.EnableDebugMode((apiCallDetails) =>
                //{
                //    // 请求完成 返回 apiCallDetails
                //});
    
                // 抛出异常,默认false,错误信息在每个操作的response中
                settings.ThrowExceptions(config.ThrowExceptions);
                //settings.OnRequestCompleted(apiCallDetails =>
                //{
                //    // 请求完成 返回apiCallDetails
                //});
                //settings.OnRequestDataCreated(requestData =>
                //{
                //    // 请求的数据创建完成 返回请求的数据
                //});
            }
    
        }
    

      ElasticsearchException

    /// <summary>
        /// Elasticsearch 异常
        /// </summary>
        [Serializable]
        public class ElasticsearchException : Exception
        {
            /// <summary>
            /// 初始化一个<see cref="ElasticsearchException"/>类型的实例
            /// </summary>
            public ElasticsearchException() { }
    
            /// <summary>
            /// 初始化一个<see cref="ElasticsearchException"/>类型的实例
            /// </summary>
            /// <param name="serializationInfo">序列号信息</param>
            /// <param name="context">流上下文</param>
            public ElasticsearchException(SerializationInfo serializationInfo, StreamingContext context) : base(serializationInfo, context)
            { 
            
            }
    
            /// <summary>
            /// 初始化一个<see cref="ElasticsearchException"/>类型的实例
            /// </summary>
            /// <param name="message">错误消息</param>
            public ElasticsearchException(string message) : base(message) { }
    
            /// <summary>
            /// 初始化一个<see cref="ElasticsearchException"/>类型的实例
            /// </summary>
            /// <param name="message">错误消息</param>
            /// <param name="innerException">内部异常</param>
            public ElasticsearchException(string message, Exception innerException) : base(message, innerException) { }
        }
    

      IElasticsearchClient

    /// <summary>
        /// ES客户端
        /// </summary>
        public interface IElasticsearchClient
        {
            /// <summary>
            /// 是否存在指定索引
            /// </summary>
            /// <param name="indexName">索引名</param>
            /// <returns></returns>
            Task<bool> ExistsAsync(string indexName);
    
            /// <summary>
            /// 添加索引。不映射
            /// </summary>
            /// <param name="indexName">索引名</param>
            Task AddAsync(string indexName);
    
            /// <summary>
            /// 添加索引。自动映射实体属性
            /// </summary>
            /// <typeparam name="T">实体类型</typeparam>
            /// <param name="indexName">索引名</param>
            Task AddAsync<T>(string indexName) where T : class;
    
            /// <summary>
            /// 添加索引。自动映射实体属性并赋值
            /// </summary>
            /// <typeparam name="T">实体类型</typeparam>
            /// <param name="indexName">索引名</param>
            /// <param name="entity">实体</param>
            /// <returns></returns>
            Task AddAsync<T>(string indexName, T entity) where T : class;
    
            /// <summary>
            /// 更新索引。
            /// 由于是普通的简单更新,当ID已经存在时,则会更新文档,所以这里直接调用index方法(复杂方法待研究)
            /// </summary>
            /// <typeparam name="T">实体类型</typeparam>
            /// <param name="indexName">索引名</param>
            /// <param name="entity">实体</param>
            Task UpdateAsync<T>(string indexName, T entity) where T : class;
        }
    

      

  • 相关阅读:
    System.in.read() 回车
    eclipse for C/C++
    J2EE和Java EE
    MySQL中的string类型
    javac: 无效的标记: FilesJavajdk1
    java eclipse com.mysql.jdbc.Driver
    (转)apache外网不能访问分析与解决方法
    jvm调优
    java性能调优03
    java性能调优02
  • 原文地址:https://www.cnblogs.com/sunliyuan/p/14473886.html
Copyright © 2011-2022 走看看