162 lines
5.6 KiB
C#
162 lines
5.6 KiB
C#
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<StringResponse>(index, type, id, json);
|
|
|
|
var code = (HttpStatusCode)indexResponse.HttpStatusCode.GetValueOrDefault((int)HttpStatusCode.ServiceUnavailable);
|
|
return code;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
return HttpStatusCode.ServiceUnavailable;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Search for statistics matching the specified <paramref name="query"/>
|
|
/// </summary>
|
|
/// <param name="index"></param>
|
|
/// <param name="query">Specify the search filter here</param>
|
|
/// <param name="size">Number of rows returned</param>
|
|
/// <param name="debug">Keeps additional information to help debugging but is less efficient.</param>
|
|
/// <remarks>
|
|
/// See how to write queries on NEST help:
|
|
/// https://www.elastic.co/guide/en/elasticsearch/client/net-api/1.x/writing-queries.html
|
|
/// </remarks>
|
|
public IEnumerable<T> Search<T>(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<ISort> { new SortField { Field = "DateTime", Order = SortOrder.Descending, UnmappedType = FieldType.Boolean } },
|
|
Query = query,
|
|
};
|
|
|
|
var result = Client.Search<T>(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<ElasticClientInstance> _clients = new List<ElasticClientInstance>();
|
|
|
|
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<T> Search<T>(string index, QueryContainer query = null, int size = 1000, bool debug = false)
|
|
where T : class
|
|
{
|
|
return clientInstance.Search<T>(index, query, size, debug);
|
|
}
|
|
|
|
/// <summary>
|
|
/// See how to connect to elastic on:
|
|
/// http://nest.azurewebsites.net/elasticsearch-net/connecting.html
|
|
/// </summary>
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|