elasticsearch7.x
[ExposeServices(isSingleton: true)]
public class ElasticSearchServer : IElasticSearchServer
{
public IElasticClient ElasticLinqClient { get; set; }
public IElasticLowLevelClient ElasticJsonClient { get; set; }
public ElasticSearchServer(ESConfig esConfig)
{
var urls = esConfig.Urls.ConvertAll(x => new Uri(x));
var connectonPool = new StaticConnectionPool(urls);
var settings=new ConnectionSettings(connectonPool).RequestTimeout(TimeSpan.FromSeconds(esConfig.Timeout));
this.ElasticJsonClient=new ElasticLowLevelClient(settings);
this.ElasticLinqClient= new ElasticClient(settings);//linq请求客户端初始化
}
#region 创建Index。指定分片
/// <summary>
/// 创建Index,如果已经存在则返回
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="indexName">index名称</param>
/// <param name="numberOfReplicas">副本数量</param>
/// <param name="numberOfShards">分片数量</param>
/// <returns></returns>
public async Task<bool> CreateIndexAsync<T>(string indexName,
int numberOfReplicas,
int numberOfShards,
CancellationToken cancellationToken = default) where T : class
{
var indexExistInfo = this.ElasticLinqClient.Indices.ExistsAsync(indexName,
item => item.IgnoreUnavailable(false),
cancellationToken);
var indexExist = await indexExistInfo;
if (indexExist.IsValid)
{
return true;
}
CreateIndexResponse result =
await this.ElasticLinqClient.Indices.CreateAsync(index: indexName, index =>
{
index.Map<T>(x => x.AutoMap<T>());
index.Settings(setting =>
{
setting.NumberOfShards(numberOfShards);
setting.NumberOfReplicas(numberOfReplicas);
setting.RefreshInterval(TimeSpan.FromSeconds(10));
return setting;
});
return index;
}
);
return result.IsValid;
}
/// <summary>
/// 删除index
/// </summary>
/// <param name="indexName"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task DeleteIndexAsync(string indexName,
CancellationToken cancellationToken = default)
{
var indexExistInfo = this.ElasticLinqClient.Indices.ExistsAsync(indexName,
item => item.IgnoreUnavailable(false),
cancellationToken);
var indexExist = await indexExistInfo;
if (indexExist.IsValid) //存在Index
{
await this.ElasticLinqClient.Indices.DeleteAsync(indexName,
item=>item.IgnoreUnavailable(false),
cancellationToken);
}
}
#endregion
#region 创建document,批量创建,删除document,批量删除,修改document,批量修改
/// <summary>
/// 插入单条document
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public async Task<bool> InsertDocumentAsync<T>(string indexName,T t,CancellationToken cancellationToken=default) where T:class
{
try
{
await this.ElasticLinqClient.IndexAsync(t, i => i.Index(indexName),cancellationToken);
return true;
}
catch (Exception)
{
return false;
}
}
public bool InsertBulkDocuments<T>(string indexName, IEnumerable<T> list,int size=1000, CancellationToken cancellationToken = default) where T : class
{
try
{
var observableBulk = this.ElasticLinqClient.BulkAll(list, f => f.MaxDegreeOfParallelism(8).
BackOffTime(TimeSpan.FromSeconds(10)).
BackOffRetries(2).
Size(size).
RefreshOnCompleted().
Index(indexName).
BufferToBulk((r, buffer) => r.IndexMany(buffer)),
cancellationToken);
var countdownEvent = new CountdownEvent(1);
var bulkAllObserver = new BulkAllObserver(
onNext: response =>
{
// WriteLine($"Indexed {response.Page * size} with {response.Retries} retries");
},
onError: ex =>
{
// WriteLine("BulkAll Error : {0}", ex);
// exception = ex;
countdownEvent.Signal();
},
() =>
{
// WriteLine("BulkAll Finished");
countdownEvent.Signal();
});
observableBulk.Subscribe(bulkAllObserver);
countdownEvent.Wait(cancellationToken);
return true;
}
catch (Exception)
{
return false;
}
}
/// <summary>
/// 删除指定条件的document
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="indexName"></param>
/// <param name="deleteProperty"></param>
/// <param name="deleteValue"></param>
/// <param name="clusterName"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<bool> DeleteBulkDocument<T>(string indexName,
string deleteProperty,
string deleteValue,
string clusterName= "lcn_elasticsearch",
CancellationToken cancellationToken=default) where T : class
{
var esContent=
await this.ElasticLinqClient.DeleteByQueryAsync<T>(p => p.Index(indexName).Query(op => op.Match(
x => x.Field(deleteProperty).Query(deleteValue)
)),cancellationToken);
return esContent.IsValid;
}
#endregion
#region 搜索
public async Task<IEnumerable<T>> SearchAsync<T>(List<string> indexNameList,
string searchProperty,
string searchValue,
string clusterName= "lcn_elasticsearch",
CancellationToken cancellationToken=default) where T:class
{
List<IndexName> indexNames = indexNameList.ConvertAll<IndexName>(x => {
IndexName indexName = x;
return indexName;
});
Indices indices = indexNames.ToArray();
var esContent =await this.ElasticLinqClient.SearchAsync<T>(p => p.Index(indices).Query(
op=>op.Match(x=>x.Field(searchProperty).Query(searchValue))
),cancellationToken);
return esContent.Documents;
}
public async Task<IEnumerable<T>> SearchPagingAsync<T>(List<string> indexNameList,
int pageSize,
int pageIndex,
string searchProperty,
string searchValue,
string clusterName = "lcn_elasticsearch",
CancellationToken cancellationToken = default) where T : class
{
List<IndexName> indexNames = indexNameList.ConvertAll<IndexName>(x => {
IndexName indexName = x;
return indexName;
});
Indices indices = indexNames.ToArray();
var esContent = await this.ElasticLinqClient.SearchAsync<T>(p => p.Index(indices).From(pageIndex).Size(pageSize).
Query(
op => op.Match(x => x.Field(searchProperty).Query(searchValue))
), cancellationToken);
return esContent.Documents;
}
#endregion
}