using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Net; using Elasticsearch.Net; using Nest; using Newtonsoft.Json; namespace JD.ElasticSearch { public class ElasticSearchClient { public class ElasticClientInstance { public ElasticClient Client {get; set;} public string[] Uri {get; set;} public string UserName { get; set; } public string Password { get; set; } public ElasticClientInstance(ElasticClient client, string[] uri, string userName , string password) { Client = client; Uri = uri; UserName = userName; Password = password; } public HttpStatusCode PutDocument(string index, string type, string id, object document) { try { string json = JsonConvert.SerializeObject(document); var indexResponse = Client.LowLevel.Index(index, type, id, json); var code = (HttpStatusCode)indexResponse.HttpStatusCode.GetValueOrDefault((int)HttpStatusCode.ServiceUnavailable); return code; } catch (Exception) { return HttpStatusCode.ServiceUnavailable; } } /// /// Search for statistics matching the specified /// /// /// Specify the search filter here /// Number of rows returned /// Keeps additional information to help debugging but is less efficient. /// /// See how to write queries on NEST help: /// https://www.elastic.co/guide/en/elasticsearch/client/net-api/1.x/writing-queries.html /// public IEnumerable Search(string index, QueryContainer query = null, int size = 1000, bool debug = false) where T : class { var request = new SearchRequest(index + "*", typeof(T).Name) { From = 0, Size = size, Sort = new List { new SortField { Field = "DateTime", Order = SortOrder.Descending, UnmappedType = FieldType.Boolean } }, Query = query, }; var result = Client.Search(request); if (debug) { Trace.WriteLine($"{result.DebugInformation}"); } return result.Hits.Select(x => x.Source); } public bool IsEquivalentClient(string[] connectionNodes, string userName, string password) { if(!Enumerable.SequenceEqual(connectionNodes, Uri)) { return false; } if(!UserName.Equals(userName)) { return false; } if(!Password.Equals(password)) { return false; } return true; } } //private static uint maxClients = 5; private static List _clients = new List(); private ElasticClientInstance clientInstance; public ElasticSearchClient(string[] connectionNodes, string userName = "", string password = "", string defaultIndex = "*") { clientInstance = CreateHighLevelClient(connectionNodes, userName, password, defaultIndex); } public HttpStatusCode PutDocument(string index, string type, string id, object document) { return clientInstance.PutDocument(index, type, id, document); } public IEnumerable Search(string index, QueryContainer query = null, int size = 1000, bool debug = false) where T : class { return clientInstance.Search(index, query, size, debug); } /// /// See how to connect to elastic on: /// http://nest.azurewebsites.net/elasticsearch-net/connecting.html /// public static ElasticClientInstance CreateHighLevelClient(string[] connectionNodes, string userName, string password, string defaultIndex, bool debug = false) { for (int i = 0; i < _clients.Count; ++i) { if (_clients[i].IsEquivalentClient(connectionNodes, userName, password)) { return _clients[i]; } } var nodesUri = connectionNodes.Select(x => new Uri(x)); // Using a connection pool allows to "round robin" on the different nodes var connectionPool = new StaticConnectionPool(nodesUri); var config = new ConnectionSettings(connectionPool); config.BasicAuthentication(userName, password); config.RequestTimeout(TimeSpan.FromSeconds(10)); config.DefaultIndex(defaultIndex); if (debug) { // This allows to inspect the queries results. config.DisableDirectStreaming(); } var elasticClient = new ElasticClient(config); var newClient = new ElasticClientInstance(elasticClient, connectionNodes, userName, password); _clients.Add(newClient); return newClient; } } }