using ElasticSearchDbAndNest.Attributes; | |
using Nest; | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Web; | |
namespace ElasticSearchDbAndNest.Models | |
{ | |
[ElasticIndexDetails("company", false)] | |
[ElasticsearchType(Name = "company")] | |
public class Company : EntityBase | |
{ | |
[Keyword(Name="companyName")] | |
public string CompanyName { get; set; } | |
} | |
} |
using ElasticSearchDbAndNest.Models; | |
using ElasticSearchDbAndNest.Repositories; | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Net; | |
using System.Net.Http; | |
using System.Threading.Tasks; | |
using System.Web.Http; | |
using System.Web.Http.Description; | |
namespace ElasticSearchDbAndNest.Controllers | |
{ | |
public class CompanyController : ApiController | |
{ | |
private RepositoryBase<Company, string> _companyRepo; | |
private RepositoryBase<Log, string> _logRepo; | |
public CompanyController() | |
{ | |
_companyRepo = new RepositoryBase<Company,string>(); | |
_logRepo = new RepositoryBase<Log, string>(); | |
} | |
/// <summary> | |
/// Inserts the company record on ElasticDB | |
/// </summary> | |
/// <param name="company"></param> | |
/// <returns></returns> | |
[HttpPost] | |
[Route("Create")] | |
[ResponseType((typeof(Company)))] | |
public IHttpActionResult CreateCompany(Company company) | |
{ | |
var result = _companyRepo.Insert(company); | |
Log log = new Log() { LogType = "Info", Description = $"Created company in DB, company name : {company.CompanyName}" }; | |
_logRepo.Insert(log); | |
return Ok(result); | |
} | |
[HttpGet] | |
[Route("GetAll")] | |
[ResponseType((typeof(Company)))] | |
public IHttpActionResult GetAllCompanies() | |
{ | |
var result = _companyRepo.GetAll(); | |
return Ok(result); | |
} | |
[HttpGet] | |
[Route("GetAllRaw")] | |
[ResponseType((typeof(Company)))] | |
public IHttpActionResult GetAllCompaniesRaw() | |
{ | |
var result = _companyRepo.GetAllRaw(); | |
return Ok(result); | |
} | |
} | |
} |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Web; | |
namespace ElasticSearchDbAndNest.Attributes | |
{ | |
[AttributeUsage(AttributeTargets.Class)] | |
public class ElasticIndexDetailsAttribute : Attribute | |
{ | |
private readonly string _indexName; | |
private readonly bool _timeSeries; | |
public ElasticIndexDetailsAttribute(string name, bool timeSeries) | |
{ | |
_indexName = name; | |
_timeSeries = timeSeries; | |
} | |
//Name of the index | |
public string IndexName | |
{ | |
get { return _indexName; } | |
} | |
//Flag for time based index | |
public bool IsTimeSeries | |
{ | |
get { return _timeSeries; } | |
} | |
} | |
} |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Web; | |
namespace ElasticSearchDbAndNest.Models | |
{ | |
public class EntityBase | |
{ | |
public string Id { get; set; } | |
} | |
} |
using ElasticSearchDbAndNest.Attributes; | |
using Nest; | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Web; | |
namespace ElasticSearchDbAndNest.Models | |
{ | |
[ElasticIndexDetails("all_log", true)] | |
[ElasticsearchType(Name = "log")] | |
public class Log : EntityBase | |
{ | |
[Text(Name="logType")] | |
public string LogType { get; set; } | |
[Text(Name="description")] | |
public string Description { get; set; } | |
} | |
} |
using Elasticsearch.Net; | |
using ElasticSearchDbAndNest.Attributes; | |
using ElasticSearchDbAndNest.Models; | |
using Nest; | |
using System; | |
using System.Collections.Generic; | |
using System.Configuration; | |
using System.Linq; | |
using System.Web; | |
namespace ElasticSearchDbAndNest.Repositories | |
{ | |
public class RepositoryBase<TEntity, TIdentifier> where TEntity : EntityBase | |
{ | |
protected IElasticClient _client; | |
private static readonly string _scrollTime = "5m"; | |
//private string _connectionName; | |
private object _lockObj = new object(); | |
public RepositoryBase() | |
{ | |
CreateElasticSearchClient(); | |
} | |
private void CreateElasticSearchClient() | |
{ | |
lock (_lockObj) | |
{ | |
if (_client == null) | |
{ | |
var connectionString = ConfigurationManager.AppSettings["ElasticSearchConnection"]; | |
var uri = new Uri(connectionString, UriKind.Absolute); | |
_client = CreateClient(uri); | |
} | |
} | |
} | |
private static IElasticClient CreateClient(Uri connectionString) | |
{ | |
var node = new UriBuilder(connectionString); | |
var connectionPool = new SingleNodeConnectionPool(node.Uri); | |
var connectionSettings = new ConnectionSettings(connectionPool); | |
return new ElasticClient(connectionSettings); | |
} | |
public TEntity GetById(TIdentifier id) | |
{ | |
var response = _client.Get<TEntity>(new DocumentPath<TEntity>(id.ToString()), g => g.Index(GetIndex<TEntity>())); | |
if (response.Source != null) | |
response.Source.Id = response.Id; | |
return response.Source; | |
} | |
public List<TEntity> GetAll() | |
{ | |
List<TEntity> all = null; | |
var result = GetPaginatedData(0, 2000); | |
all = result.Results; | |
return all; | |
} | |
public List<TEntity> GetAllRaw() | |
{ | |
ISearchResponse<TEntity> response = _client.Search<TEntity>(s => s | |
.Index(GetIndex<TEntity>()) | |
.From(0) | |
.Size(200) | |
.SearchType(Elasticsearch.Net.SearchType.QueryThenFetch)); | |
return response.Documents.ToList(); | |
} | |
private SearchResult<TEntity> GetPaginatedData(int from, int size, QueryContainer query = null) | |
{ | |
ISearchResponse<TEntity> response = _client.Search<TEntity>(s => s | |
.Index(GetIndex<TEntity>()) | |
.From(from) | |
.Size(size) | |
.Query(q => query) | |
.SearchType(Elasticsearch.Net.SearchType.QueryThenFetch)); | |
return GetSearchResults(response); | |
} | |
private static SearchResult<TEntity> GetSearchResults(ISearchResponse<TEntity> response) | |
{ | |
var documents = response.Hits.Select(hit => | |
{ | |
var result = hit.Source; | |
result.Id = hit.Id; | |
return result; | |
}).ToList(); | |
return new SearchResult<TEntity>(documents, response.ScrollId); | |
} | |
public string Insert(TEntity doc) | |
{ | |
var response = _client.Index<TEntity>(doc, g => g.Index(GetIndex<TEntity>())); | |
return response.Id; | |
} | |
private static string GetIndex<T>() | |
{ | |
var details = GetCustomAttribute<T, ElasticIndexDetailsAttribute>(); | |
if (details == null) | |
{ | |
throw new Exception("ElasticIndexDetailsAttribute has not been set for the type " + typeof(T).FullName); | |
} | |
var index = details.IndexName; | |
if (!details.IsTimeSeries) | |
{ | |
return index; | |
} | |
var date = DateTime.UtcNow.Date.ToShortDateString().Replace('-','_'); | |
return $"{index}_{date}"; | |
} | |
private static TAttr GetCustomAttribute<T, TAttr>() | |
{ | |
Type type = typeof(T); | |
TAttr[] attribs = type.GetCustomAttributes( | |
typeof(TAttr), false) as TAttr[]; | |
return attribs[0]; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment