diff --git a/samples/Bing.Elasticsearch.WinformSample/Bing.Elasticsearch.WinformSample.csproj b/samples/Bing.Elasticsearch.WinformSample/Bing.Elasticsearch.WinformSample.csproj
index 81409e8..04e1772 100644
--- a/samples/Bing.Elasticsearch.WinformSample/Bing.Elasticsearch.WinformSample.csproj
+++ b/samples/Bing.Elasticsearch.WinformSample/Bing.Elasticsearch.WinformSample.csproj
@@ -6,6 +6,10 @@
true
+
+
+
+
diff --git a/src/Bing.Elasticsearch/Bing.Elasticsearch.xml b/src/Bing.Elasticsearch/Bing.Elasticsearch.xml
index 5e851d8..9c434d0 100644
--- a/src/Bing.Elasticsearch/Bing.Elasticsearch.xml
+++ b/src/Bing.Elasticsearch/Bing.Elasticsearch.xml
@@ -29,12 +29,18 @@
ES选项配置
-
+
+
+ ES映射工厂
+
+
+
初始化一个类型的实例
ES客户端提供程序
索引名称解析器
+ ES映射工厂
ES选项配置
@@ -358,6 +364,16 @@
每个主分片的副分片数量
取消令牌
+
+
+ 创建索引
+
+ 实体类型
+ ES客户端
+ ES映射工厂
+ 索引名
+ 取消令牌
+
ES上下文扩展
@@ -685,12 +701,252 @@
文档类型
索引名称。注意:必须小写
+
+
+ 安全获取索引名称
+
+ 文档类型
+ 索引名称。注意:必须小写
+
获取ES标识
标识
+
+
+ 默认映射
+
+
+
+
+ 初始化一个类型的实例
+
+ 类型
+ ES选项配置
+
+
+
+ 配置索引
+
+ 创建索引描述符
+
+
+
+ 配置索引设置
+
+ 索引设置描述符
+
+
+
+ ES 映射
+
+
+
+
+ 类型
+
+
+
+
+ 索引名称
+
+
+
+
+ 是否拥有多个索引
+
+
+
+
+ ES选项配置
+
+
+
+
+ 初始化一个类型的实例
+
+ 类型
+ ES选项配置
+
+
+
+ 映射
+
+ 创建索引描述符
+
+
+
+ 配置索引
+
+ 创建索引描述符
+
+
+
+ 配置索引别名
+
+ 别名描述符
+
+
+
+ 配置索引设置
+
+ 索引设置描述符
+
+
+
+ ES映射
+
+ 实体类型
+
+
+
+ 初始化一个类型的实例
+
+ 类型
+ ES选项配置
+
+
+
+ 配置索引映射
+
+ 映射
+
+
+
+ 配置索引
+
+ 创建索引描述符
+
+
+
+ ES映射工厂
+
+
+
+
+ 反射实例类型
+
+
+
+
+ ES选项配置
+
+
+
+
+ ES映射 类型查找器
+
+
+
+
+ 映射字典
+
+
+
+
+ 初始化一个类型的实例
+
+ ES选项配置
+ ES映射 类型查找器
+
+
+
+ 初始化映射
+
+
+
+
+ 获取ES映射类
+
+ 类型
+
+
+
+ 获取ES映射类
+
+ 泛型类型
+
+
+
+ ES映射 类型查找器
+
+
+
+
+ 所有程序集查找器
+
+
+
+
+ 初始化一个类型的实例
+
+ 所有程序集查找器
+
+
+
+
+
+
+ ES映射
+
+
+
+
+ 类型
+
+
+
+
+ 索引名称
+
+
+
+
+ 是否拥有多个索引
+
+
+
+
+ 映射
+
+ 创建索引描述符
+
+
+
+ ES映射
+
+ 实体类型
+
+
+
+ 配置索引映射
+
+ 映射
+
+
+
+ ES映射工厂
+
+
+
+
+ 获取ES映射类
+
+ 类型
+
+
+
+ 获取ES映射类
+
+ 泛型类型
+
+
+
+ ES映射 类型查找器
+
+
高亮参数
diff --git a/src/Bing.Elasticsearch/ElasticsearchContext.cs b/src/Bing.Elasticsearch/ElasticsearchContext.cs
index 6d2777b..dc692be 100644
--- a/src/Bing.Elasticsearch/ElasticsearchContext.cs
+++ b/src/Bing.Elasticsearch/ElasticsearchContext.cs
@@ -4,6 +4,7 @@
using System.Threading;
using System.Threading.Tasks;
using Bing.Elasticsearch.Internals;
+using Bing.Elasticsearch.Mapping;
using Bing.Elasticsearch.Options;
using Bing.Elasticsearch.Provider;
using Bing.Elasticsearch.Repositories;
@@ -39,16 +40,23 @@ public class ElasticsearchContext : IElasticsearchContext
///
private readonly ElasticsearchOptions _options;
+ ///
+ /// ES映射工厂
+ ///
+ private readonly IElasticMappingFactory _mappingFactory;
+
///
/// 初始化一个类型的实例
///
/// ES客户端提供程序
/// 索引名称解析器
+ /// ES映射工厂
/// ES选项配置
- public ElasticsearchContext(IElasticClientProvider provider, IIndexNameResolver resolver, IOptions options)
+ public ElasticsearchContext(IElasticClientProvider provider, IIndexNameResolver resolver, IElasticMappingFactory mappingFactory, IOptions options)
{
_provider = provider;
_resolver = resolver;
+ _mappingFactory = mappingFactory;
_client = provider.GetClient();
_options = options.Value;
}
@@ -117,7 +125,8 @@ public async Task CreateIndexAsync(string index, string ali
/// 取消令牌
public async Task CreateIndexAsync(string index, string alias = null, CancellationToken cancellationToken = default) where TDocument : class
{
- await _client.CreateIndexAsync(index, _options.NumberOfShards, _options.NumberOfReplicas, cancellationToken);
+ //await _client.CreateIndexAsync(index, _options.NumberOfShards, _options.NumberOfReplicas, cancellationToken);
+ await _client.CreateIndexAsync(_mappingFactory, index, cancellationToken);
if (alias.IsEmpty() == false)
await _client.Indices.PutAliasAsync(index, alias, ct: cancellationToken);
}
diff --git a/src/Bing.Elasticsearch/Extensions.Service.cs b/src/Bing.Elasticsearch/Extensions.Service.cs
index f3e7796..4fe8685 100644
--- a/src/Bing.Elasticsearch/Extensions.Service.cs
+++ b/src/Bing.Elasticsearch/Extensions.Service.cs
@@ -1,4 +1,5 @@
using System;
+using Bing.Elasticsearch.Mapping;
using Bing.Elasticsearch.Options;
using Bing.Elasticsearch.Provider;
using Bing.Elasticsearch.Repositories;
@@ -20,9 +21,12 @@ public static partial class Extensions
public static void AddElasticsearch(this IServiceCollection services, Action setupAction)
{
services.Configure(setupAction);
+ services.GetOrAddAllAssemblyFinder();
+ services.GetOrAddTypeFinder(assemblyFinder => new ElasticMappingTypeFinder(assemblyFinder));
services.TryAddSingleton();
services.TryAddSingleton();
services.TryAddScoped();
+ services.TryAddSingleton();
services.TryAddScoped(typeof(IEsRepository<>), typeof(EsRepository<>));
}
}
diff --git a/src/Bing.Elasticsearch/Extensions/ElasticClientExtensions.cs b/src/Bing.Elasticsearch/Extensions/ElasticClientExtensions.cs
index 8ab2c22..66f68b0 100644
--- a/src/Bing.Elasticsearch/Extensions/ElasticClientExtensions.cs
+++ b/src/Bing.Elasticsearch/Extensions/ElasticClientExtensions.cs
@@ -1,6 +1,7 @@
using System.Threading;
using System.Threading.Tasks;
using Bing.Elasticsearch.Internals;
+using Bing.Elasticsearch.Mapping;
using Nest;
// ReSharper disable once CheckNamespace
@@ -31,10 +32,9 @@ public static async Task CreateIndexAsync(this IElasticClient client,
var existsResult = await client.Indices.ExistsAsync(indexName, null, cancellationToken);
if (existsResult.Exists)
return;
-
var result = await client.Indices.CreateAsync(
indexName,
- x => x.Map(m=>m.AutoMap())
+ x => x.Map(m => m.AutoMap())
.Settings(o =>
o.NumberOfShards(numberOfShards)
.NumberOfReplicas(numberOfReplicas)
@@ -43,5 +43,36 @@ public static async Task CreateIndexAsync(this IElasticClient client,
if (!result.Acknowledged)
throw new ElasticsearchException($"索引[{indexName}]创建失败:{result.ServerError.Error.Reason}");
}
+
+ ///
+ /// 创建索引
+ ///
+ /// 实体类型
+ /// ES客户端
+ /// ES映射工厂
+ /// 索引名
+ /// 取消令牌
+ public static async Task CreateIndexAsync(this IElasticClient client,
+ IElasticMappingFactory factory,
+ string indexName = "",
+ CancellationToken cancellationToken = default)
+ where T : class
+ {
+ indexName = Helper.SafeIndexName(indexName);
+ var existsResult = await client.Indices.ExistsAsync(indexName, null, cancellationToken);
+ if (existsResult.Exists)
+ return;
+ var mapping = factory.GetMapping();
+ var result = await client.Indices.CreateAsync(
+ indexName,
+ x =>
+ {
+ mapping.Map(x);
+ return x;
+ },
+ cancellationToken);
+ if (!result.Acknowledged)
+ throw new ElasticsearchException($"索引[{indexName}]创建失败:{result.ServerError.Error.Reason}");
+ }
}
}
diff --git a/src/Bing.Elasticsearch/Internals/Helper.cs b/src/Bing.Elasticsearch/Internals/Helper.cs
index 374757b..776691f 100644
--- a/src/Bing.Elasticsearch/Internals/Helper.cs
+++ b/src/Bing.Elasticsearch/Internals/Helper.cs
@@ -20,11 +20,17 @@ internal static class Helper
///
/// 文档类型
/// 索引名称。注意:必须小写
- public static string SafeIndexName(string index = null)
+ public static string SafeIndexName(string index = null) => SafeIndexName(typeof(TDocument), index);
+
+ ///
+ /// 安全获取索引名称
+ ///
+ /// 文档类型
+ /// 索引名称。注意:必须小写
+ public static string SafeIndexName(Type type, string index = null)
{
if (index.IsEmpty() == false)
return index;
- var type = typeof(TDocument);
if (!IndexCacheDict.ContainsKey(type))
{
var elasticsearchTypeAttribute = type.GetAttribute();
diff --git a/src/Bing.Elasticsearch/Mapping/DefaultElasticMapping.cs b/src/Bing.Elasticsearch/Mapping/DefaultElasticMapping.cs
new file mode 100644
index 0000000..670406d
--- /dev/null
+++ b/src/Bing.Elasticsearch/Mapping/DefaultElasticMapping.cs
@@ -0,0 +1,42 @@
+using System;
+using Bing.Elasticsearch.Options;
+using Nest;
+
+namespace Bing.Elasticsearch.Mapping
+{
+ ///
+ /// 默认映射
+ ///
+ public class DefaultElasticMapping : ElasticMapping, IElasticMapping
+ {
+ ///
+ /// 初始化一个类型的实例
+ ///
+ /// 类型
+ /// ES选项配置
+ public DefaultElasticMapping(Type type, ElasticsearchOptions options) : base(type, options)
+ {
+ }
+
+ ///
+ /// 配置索引
+ ///
+ /// 创建索引描述符
+ public override CreateIndexDescriptor ConfigureIndex(CreateIndexDescriptor idx)
+ {
+ idx = base.ConfigureIndex(idx);
+ return idx.Map(x => x.AutoMap(Type));
+ }
+
+ ///
+ /// 配置索引设置
+ ///
+ /// 索引设置描述符
+ public override IPromise ConfigureIndexSettings(IndexSettingsDescriptor settings)
+ {
+ return settings.NumberOfShards(Options.NumberOfShards)
+ .NumberOfReplicas(Options.NumberOfReplicas)
+ .Setting("max_result_window", int.MaxValue);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Bing.Elasticsearch/Mapping/ElasticMapping.cs b/src/Bing.Elasticsearch/Mapping/ElasticMapping.cs
new file mode 100644
index 0000000..85b26c9
--- /dev/null
+++ b/src/Bing.Elasticsearch/Mapping/ElasticMapping.cs
@@ -0,0 +1,120 @@
+using System;
+using Bing.Elasticsearch.Internals;
+using Bing.Elasticsearch.Options;
+using Nest;
+
+namespace Bing.Elasticsearch.Mapping
+{
+ ///
+ /// ES 映射
+ ///
+ public class ElasticMapping : IElasticMapping
+ {
+ ///
+ /// 类型
+ ///
+ public Type Type { get; protected set; }
+
+ ///
+ /// 索引名称
+ ///
+ public string Name { get; protected set; }
+
+ ///
+ /// 是否拥有多个索引
+ ///
+ public bool HasMultipleIndexes { get; protected set; }
+
+ ///
+ /// ES选项配置
+ ///
+ protected ElasticsearchOptions Options { get; }
+
+ ///
+ /// 初始化一个类型的实例
+ ///
+ /// 类型
+ /// ES选项配置
+ public ElasticMapping(Type type, ElasticsearchOptions options)
+ {
+ Type = type;
+ Name = Helper.SafeIndexName(type);
+ Options = options;
+ }
+
+ ///
+ /// 映射
+ ///
+ /// 创建索引描述符
+ public void Map(CreateIndexDescriptor descriptor)
+ {
+ ConfigureIndex(descriptor);
+ }
+
+ ///
+ /// 配置索引
+ ///
+ /// 创建索引描述符
+ public virtual CreateIndexDescriptor ConfigureIndex(CreateIndexDescriptor idx)
+ {
+ return idx
+ .Aliases(ConfigureIndexAliases)
+ .Settings(ConfigureIndexSettings);
+ }
+
+ ///
+ /// 配置索引别名
+ ///
+ /// 别名描述符
+ public virtual IPromise ConfigureIndexAliases(AliasesDescriptor aliases)
+ {
+ return aliases;
+ }
+
+ ///
+ /// 配置索引设置
+ ///
+ /// 索引设置描述符
+ public virtual IPromise ConfigureIndexSettings(IndexSettingsDescriptor settings)
+ {
+ return settings;
+ }
+ }
+
+ ///
+ /// ES映射
+ ///
+ /// 实体类型
+ public class ElasticMapping : ElasticMapping, IElasticMapping where T : class
+ {
+ ///
+ /// 初始化一个类型的实例
+ ///
+ /// 类型
+ /// ES选项配置
+ public ElasticMapping(Type type, ElasticsearchOptions options) : base(type, options)
+ {
+ Type = typeof(T);
+ Name = Helper.SafeIndexName(type);
+ }
+
+ ///
+ /// 配置索引映射
+ ///
+ /// 映射
+ public virtual TypeMappingDescriptor ConfigureIndexMapping(TypeMappingDescriptor map)
+ {
+ return map.AutoMap();
+ }
+
+ ///
+ /// 配置索引
+ ///
+ /// 创建索引描述符
+ public override CreateIndexDescriptor ConfigureIndex(CreateIndexDescriptor idx)
+ {
+ idx = base.ConfigureIndex(idx);
+ return idx.Map(ConfigureIndexMapping);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Bing.Elasticsearch/Mapping/ElasticMappingFactory.cs b/src/Bing.Elasticsearch/Mapping/ElasticMappingFactory.cs
new file mode 100644
index 0000000..bf5bb33
--- /dev/null
+++ b/src/Bing.Elasticsearch/Mapping/ElasticMappingFactory.cs
@@ -0,0 +1,95 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using Bing.Elasticsearch.Options;
+using Bing.Extensions;
+using Bing.Reflection;
+using Microsoft.Extensions.Options;
+
+namespace Bing.Elasticsearch.Mapping
+{
+ ///
+ /// ES映射工厂
+ ///
+ public class ElasticMappingFactory : IElasticMappingFactory
+ {
+ ///
+ /// 反射实例类型
+ ///
+ private static readonly Type RefInstanceType = typeof(ElasticMapping<>);
+
+ ///
+ /// ES选项配置
+ ///
+ private readonly ElasticsearchOptions _options;
+
+ ///
+ /// ES映射 类型查找器
+ ///
+ private readonly IElasticMappingTypeFinder _finder;
+
+ ///
+ /// 映射字典
+ ///
+ protected Dictionary MappingDict { get; }
+
+ ///
+ /// 初始化一个类型的实例
+ ///
+ /// ES选项配置
+ /// ES映射 类型查找器
+ public ElasticMappingFactory(IOptions options, IElasticMappingTypeFinder finder)
+ {
+ _options = options.Value;
+ _finder = finder;
+ MappingDict = new Dictionary();
+ InitMapping();
+ }
+
+ ///
+ /// 初始化映射
+ ///
+ protected virtual void InitMapping()
+ {
+ var maps = _finder.FindAll(true);
+ foreach (var map in maps)
+ {
+ var interfaces = map.GetInterfaces();
+ foreach (var @interface in interfaces)
+ {
+ var genericArgs = @interface.GetGenericArguments();
+ if (genericArgs.Length == 1)
+ {
+ var targetType = genericArgs[0];
+ if (targetType.FullName == null)
+ continue;
+ var implementType = RefInstanceType.MakeGenericType(targetType);
+ MappingDict[targetType] = (IElasticMapping)Activator.CreateInstance(implementType, targetType, _options);
+ }
+ }
+
+
+ }
+ }
+
+ ///
+ /// 获取ES映射类
+ ///
+ /// 类型
+ public IElasticMapping GetMapping(Type type)
+ {
+ if (MappingDict.TryGetValue(type, out var mapping))
+ {
+ return mapping;
+ }
+ return new DefaultElasticMapping(type, _options);
+ }
+
+ ///
+ /// 获取ES映射类
+ ///
+ /// 泛型类型
+ public IElasticMapping GetMapping() => GetMapping(typeof(T));
+ }
+}
\ No newline at end of file
diff --git a/src/Bing.Elasticsearch/Mapping/ElasticMappingTypeFinder.cs b/src/Bing.Elasticsearch/Mapping/ElasticMappingTypeFinder.cs
new file mode 100644
index 0000000..f5d9d83
--- /dev/null
+++ b/src/Bing.Elasticsearch/Mapping/ElasticMappingTypeFinder.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Linq;
+using Bing.Extensions;
+using Bing.Finders;
+using Bing.Reflection;
+
+namespace Bing.Elasticsearch.Mapping
+{
+ ///
+ /// ES映射 类型查找器
+ ///
+ public class ElasticMappingTypeFinder : FinderBase, IElasticMappingTypeFinder
+ {
+ ///
+ /// 所有程序集查找器
+ ///
+ private readonly IAllAssemblyFinder _allAssemblyFinder;
+
+ ///
+ /// 初始化一个类型的实例
+ ///
+ /// 所有程序集查找器
+ public ElasticMappingTypeFinder(IAllAssemblyFinder allAssemblyFinder) => _allAssemblyFinder =
+ allAssemblyFinder ?? throw new ArgumentNullException(nameof(allAssemblyFinder));
+
+ ///
+ protected override Type[] FindAllItems()
+ {
+ var assemblies = _allAssemblyFinder.FindAll(true);
+ var types = assemblies
+ .SelectMany(assembly => assembly.GetTypes().Where(type =>
+ type.IsClass &&
+ !type.IsAbstract &&
+ !type.IsInterface &&
+ typeof(IElasticMapping<>).IsGenericAssignableFrom(type)))
+ .ToArray();
+ return types;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Bing.Elasticsearch/Mapping/IElasticMapping.cs b/src/Bing.Elasticsearch/Mapping/IElasticMapping.cs
new file mode 100644
index 0000000..c42e456
--- /dev/null
+++ b/src/Bing.Elasticsearch/Mapping/IElasticMapping.cs
@@ -0,0 +1,45 @@
+using System;
+using Nest;
+
+namespace Bing.Elasticsearch.Mapping
+{
+ ///
+ /// ES映射
+ ///
+ public interface IElasticMapping
+ {
+ ///
+ /// 类型
+ ///
+ Type Type { get; }
+
+ ///
+ /// 索引名称
+ ///
+ string Name { get; }
+
+ ///
+ /// 是否拥有多个索引
+ ///
+ bool HasMultipleIndexes { get; }
+
+ ///
+ /// 映射
+ ///
+ /// 创建索引描述符
+ void Map(CreateIndexDescriptor descriptor);
+ }
+
+ ///
+ /// ES映射
+ ///
+ /// 实体类型
+ public interface IElasticMapping : IElasticMapping where T : class
+ {
+ ///
+ /// 配置索引映射
+ ///
+ /// 映射
+ TypeMappingDescriptor ConfigureIndexMapping(TypeMappingDescriptor map);
+ }
+}
\ No newline at end of file
diff --git a/src/Bing.Elasticsearch/Mapping/IElasticMappingFactory.cs b/src/Bing.Elasticsearch/Mapping/IElasticMappingFactory.cs
new file mode 100644
index 0000000..e45617a
--- /dev/null
+++ b/src/Bing.Elasticsearch/Mapping/IElasticMappingFactory.cs
@@ -0,0 +1,22 @@
+using System;
+
+namespace Bing.Elasticsearch.Mapping
+{
+ ///
+ /// ES映射工厂
+ ///
+ public interface IElasticMappingFactory
+ {
+ ///
+ /// 获取ES映射类
+ ///
+ /// 类型
+ IElasticMapping GetMapping(Type type);
+
+ ///
+ /// 获取ES映射类
+ ///
+ /// 泛型类型
+ IElasticMapping GetMapping();
+ }
+}
\ No newline at end of file
diff --git a/src/Bing.Elasticsearch/Mapping/IElasticMappingTypeFinder.cs b/src/Bing.Elasticsearch/Mapping/IElasticMappingTypeFinder.cs
new file mode 100644
index 0000000..2a87cd6
--- /dev/null
+++ b/src/Bing.Elasticsearch/Mapping/IElasticMappingTypeFinder.cs
@@ -0,0 +1,11 @@
+using Bing.Reflection;
+
+namespace Bing.Elasticsearch.Mapping
+{
+ ///
+ /// ES映射 类型查找器
+ ///
+ public interface IElasticMappingTypeFinder : ITypeFinder
+ {
+ }
+}
\ No newline at end of file
diff --git a/src/Bing.Elasticsearch/Options/ElasticsearchOptions.cs b/src/Bing.Elasticsearch/Options/ElasticsearchOptions.cs
index 4e517f5..c5c0f07 100644
--- a/src/Bing.Elasticsearch/Options/ElasticsearchOptions.cs
+++ b/src/Bing.Elasticsearch/Options/ElasticsearchOptions.cs
@@ -69,6 +69,11 @@ public class ElasticsearchOptions
///
public string Prefix { get; set; }
+ ///
+ /// 是否检查索引
+ ///
+ public bool CheckIndex { get; set; } = true;
+
///
/// 兼容版本(>=7.0)
///
diff --git a/src/Bing.Elasticsearch/Repositories/EsRepository.cs b/src/Bing.Elasticsearch/Repositories/EsRepository.cs
index 4afeb17..df3baff 100644
--- a/src/Bing.Elasticsearch/Repositories/EsRepository.cs
+++ b/src/Bing.Elasticsearch/Repositories/EsRepository.cs
@@ -6,6 +6,8 @@
using System.Threading.Tasks;
using Bing.Elasticsearch.Internals;
using Bing.Elasticsearch.Model;
+using Bing.Elasticsearch.Options;
+using Microsoft.Extensions.Options;
using Nest;
namespace Bing.Elasticsearch.Repositories
@@ -31,13 +33,20 @@ public class EsRepository : IEsRepository where TEntity : clas
///
protected virtual string IndexName { get; set; }
+ ///
+ /// ES选项配置
+ ///
+ protected ElasticsearchOptions Options { get; set; }
+
///
/// 初始化一个类型的实例
///
/// ES上下文
- public EsRepository(IElasticsearchContext context)
+ /// ES选项配置
+ public EsRepository(IElasticsearchContext context, IOptions options)
{
Context = context ?? throw new ArgumentNullException(nameof(context));
+ Options = options.Value;
_client = Context.GetClient();
IndexName = Helper.SafeIndexName(IndexName);
}
@@ -47,7 +56,7 @@ public EsRepository(IElasticsearchContext context)
///
/// 实体
/// 取消令牌
- public async Task InsertAsync(TEntity entity, CancellationToken cancellationToken = default)
+ public virtual async Task InsertAsync(TEntity entity, CancellationToken cancellationToken = default)
{
var indexName = Helper.SafeIndexName(IndexName);
await ExistOrCreateAsync(indexName, cancellationToken);
@@ -61,7 +70,7 @@ public async Task InsertAsync(TEntity entity, CancellationToken cancellationToke
///
/// 实体集合
/// 取消令牌
- public async Task InsertManyAsync(IEnumerable entities, CancellationToken cancellationToken = default)
+ public virtual async Task InsertManyAsync(IEnumerable entities, CancellationToken cancellationToken = default)
{
var indexName = Helper.SafeIndexName(IndexName);
await ExistOrCreateAsync(indexName, cancellationToken);
@@ -75,7 +84,7 @@ public async Task InsertManyAsync(IEnumerable entities, CancellationTok
///
/// 实体集合
/// 取消令牌
- public async Task BulkAsync(IEnumerable entities, CancellationToken cancellationToken = default)
+ public virtual async Task BulkAsync(IEnumerable entities, CancellationToken cancellationToken = default)
{
var indexName = Helper.SafeIndexName(IndexName);
await ExistOrCreateAsync(indexName, cancellationToken);
@@ -89,7 +98,7 @@ public async Task BulkAsync(IEnumerable entities, CancellationToken can
///
/// 实体
/// 取消令牌
- public async Task DeleteAsync(TEntity entity, CancellationToken cancellationToken = default)
+ public virtual async Task DeleteAsync(TEntity entity, CancellationToken cancellationToken = default)
{
var indexName = Helper.SafeIndexName(IndexName);
var response = await Context.DeleteAsync(entity, indexName, cancellationToken);
@@ -102,7 +111,7 @@ public async Task DeleteAsync(TEntity entity, CancellationToken cancellationToke
///
/// 标识
/// 取消令牌
- public async Task DeleteAsync(object id, CancellationToken cancellationToken = default)
+ public virtual async Task DeleteAsync(object id, CancellationToken cancellationToken = default)
{
var indexName = Helper.SafeIndexName(IndexName);
var response = await Context.DeleteAsync(id, indexName, cancellationToken);
@@ -115,7 +124,7 @@ public async Task DeleteAsync(object id, CancellationToken cancellationToken = d
///
/// 查询删除描述符
/// 取消令牌
- public async Task DeleteByQueryAsync(DeleteByQueryDescriptor descriptor, CancellationToken cancellationToken = default)
+ public virtual async Task DeleteByQueryAsync(DeleteByQueryDescriptor descriptor, CancellationToken cancellationToken = default)
{
var indexName = Helper.SafeIndexName(IndexName);
descriptor = descriptor.Index(Context.GetIndexName(IndexName));
@@ -130,7 +139,7 @@ public async Task DeleteByQueryAsync(DeleteByQueryDescriptor descriptor
///
/// 实体
/// 取消令牌
- public async Task UpdateAsync(TEntity entity, CancellationToken cancellationToken = default)
+ public virtual async Task UpdateAsync(TEntity entity, CancellationToken cancellationToken = default)
{
var indexName = Helper.SafeIndexName(IndexName);
var response = await Context.UpdateAsync(entity, indexName, cancellationToken);
@@ -144,7 +153,7 @@ public async Task UpdateAsync(TEntity entity, CancellationToken cancellationToke
/// 标识
/// 实体
/// 取消令牌
- public async Task UpdateAsync(object id, TEntity entity, CancellationToken cancellationToken = default)
+ public virtual async Task UpdateAsync(object id, TEntity entity, CancellationToken cancellationToken = default)
{
var indexName = Helper.SafeIndexName(IndexName);
var response = await Context.UpdateAsync(id, entity, indexName, cancellationToken);
@@ -157,7 +166,7 @@ public async Task UpdateAsync(object id, TEntity entity, CancellationToken cance
///
/// 查询更新描述符
/// 取消令牌
- public async Task UpdateByQueryAsync(UpdateByQueryDescriptor descriptor, CancellationToken cancellationToken = default)
+ public virtual async Task UpdateByQueryAsync(UpdateByQueryDescriptor descriptor, CancellationToken cancellationToken = default)
{
var indexName = Helper.SafeIndexName(IndexName);
descriptor = descriptor.Index(Context.GetIndexName(IndexName));
@@ -172,7 +181,7 @@ public async Task UpdateByQueryAsync(UpdateByQueryDescriptor descriptor
///
/// 标识
/// 取消令牌
- public async Task FindByIdAsync(object id, CancellationToken cancellationToken = default)
+ public virtual async Task FindByIdAsync(object id, CancellationToken cancellationToken = default)
{
var indexName = Helper.SafeIndexName(IndexName);
return await Context.FindByIdAsync(id, indexName, cancellationToken);
@@ -182,21 +191,21 @@ public async Task FindByIdAsync(object id, CancellationToken cancellati
/// 通过标识集合查找
///
/// 标识集合
- public Task> FindByIdsAsync(params string[] ids) =>
+ public virtual Task> FindByIdsAsync(params string[] ids) =>
FindByIdsAsync((IEnumerable)ids);
///
/// 通过标识集合查找
///
/// 标识集合
- public Task> FindByIdsAsync(params long[] ids) => FindByIdsAsync((IEnumerable)ids);
+ public virtual Task> FindByIdsAsync(params long[] ids) => FindByIdsAsync((IEnumerable)ids);
///
/// 通过标识集合查找
///
/// 标识集合
/// 取消令牌
- public async Task> FindByIdsAsync(IEnumerable ids, CancellationToken cancellationToken = default)
+ public virtual async Task> FindByIdsAsync(IEnumerable ids, CancellationToken cancellationToken = default)
{
var indexName = Helper.SafeIndexName(IndexName);
return await Context.FindByIdsAsync(ids, indexName, cancellationToken);
@@ -207,7 +216,7 @@ public async Task> FindByIdsAsync(IEnumerable ids,
///
/// 标识集合
/// 取消令牌
- public async Task> FindByIdsAsync(IEnumerable ids, CancellationToken cancellationToken = default)
+ public virtual async Task> FindByIdsAsync(IEnumerable ids, CancellationToken cancellationToken = default)
{
var indexName = Helper.SafeIndexName(IndexName);
return await Context.FindByIdsAsync(ids, indexName, cancellationToken);
@@ -218,7 +227,7 @@ public async Task> FindByIdsAsync(IEnumerable ids, Ca
///
/// 查询描述器
/// 取消令牌
- public async Task> SearchAsync(SearchDescriptor descriptor, CancellationToken cancellationToken = default)
+ public virtual async Task> SearchAsync(SearchDescriptor descriptor, CancellationToken cancellationToken = default)
{
var result = new List();
descriptor = descriptor.Index(Context.GetIndexName(IndexName));
@@ -245,7 +254,7 @@ public async Task> SearchAsync(SearchDescriptor d
///
/// 查询描述符
/// 取消令牌
- public async Task>> HitsSearchAsync(SearchDescriptor descriptor, CancellationToken cancellationToken = default)
+ public virtual async Task>> HitsSearchAsync(SearchDescriptor descriptor, CancellationToken cancellationToken = default)
{
descriptor = descriptor.Index(Context.GetIndexName(IndexName));
Func, ISearchRequest> selector = x => descriptor;
@@ -259,7 +268,7 @@ public async Task>> HitsSearchAsync(SearchDescriptor查询描述符
/// 键名
/// 取消令牌
- public async Task> AggregationsSearchAsync(SearchDescriptor descriptor, string key, CancellationToken cancellationToken = default)
+ public virtual async Task> AggregationsSearchAsync(SearchDescriptor descriptor, string key, CancellationToken cancellationToken = default)
{
descriptor = descriptor.Index(Context.GetIndexName(IndexName));
Func, ISearchRequest> selector = x => descriptor;
@@ -277,8 +286,10 @@ public async Task> AggregationsSearchAsync(SearchDescript
///
/// 索引名称
/// 取消令牌
- protected async Task ExistOrCreateAsync(string indexName, CancellationToken cancellationToken = default)
+ protected virtual async Task ExistOrCreateAsync(string indexName, CancellationToken cancellationToken = default)
{
+ if (!Options.CheckIndex)
+ return;
indexName = Context.GetIndexName(indexName);
var result = await _client.Indices.ExistsAsync(indexName, null, cancellationToken);
if (result.Exists)
diff --git a/src/Bing.Elasticsearch/project.dependency.props b/src/Bing.Elasticsearch/project.dependency.props
index b70abc8..a0ce409 100644
--- a/src/Bing.Elasticsearch/project.dependency.props
+++ b/src/Bing.Elasticsearch/project.dependency.props
@@ -1,8 +1,9 @@
+
-
-
+
+
\ No newline at end of file
diff --git a/tests/Bing.Elasticsearch.Tests/EsIndexTest.cs b/tests/Bing.Elasticsearch.Tests/EsIndexTest.cs
new file mode 100644
index 0000000..e054165
--- /dev/null
+++ b/tests/Bing.Elasticsearch.Tests/EsIndexTest.cs
@@ -0,0 +1,44 @@
+using System.Threading.Tasks;
+using Bing.Elasticsearch.Mapping;
+using Bing.Elasticsearch.Tests.Models;
+using Microsoft.Extensions.DependencyInjection;
+using Xunit;
+
+namespace Bing.Elasticsearch.Tests
+{
+ ///
+ /// ES索引测试
+ ///
+ public class EsIndexTest: EsTestBase
+ {
+ [Fact]
+ public async Task Test_CreateIndexAsync()
+ {
+ using var scope = ServiceProvider.CreateScope();
+ var factory = scope.ServiceProvider.GetService();
+ var mapping = factory.GetMapping();
+ var context = scope.ServiceProvider.GetService();
+ var result=await context.GetClient().Indices.CreateAsync("test_model_1", (x) =>
+ {
+ mapping.Map(x);
+ return x;
+ });
+ Assert.True(result.IsValid);
+ }
+
+ [Fact]
+ public async Task Test_CreateIndexAsync_Default()
+ {
+ using var scope = ServiceProvider.CreateScope();
+ var factory = scope.ServiceProvider.GetService();
+ var mapping = factory.GetMapping();
+ var context = scope.ServiceProvider.GetService();
+ var result = await context.GetClient().Indices.CreateAsync("test_model_5", (x) =>
+ {
+ mapping.Map(x);
+ return x;
+ });
+ Assert.True(result.IsValid);
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/Bing.Elasticsearch.Tests/EsRepositoryTest.cs b/tests/Bing.Elasticsearch.Tests/EsRepositoryTest.cs
index 1eb0af8..9833d91 100644
--- a/tests/Bing.Elasticsearch.Tests/EsRepositoryTest.cs
+++ b/tests/Bing.Elasticsearch.Tests/EsRepositoryTest.cs
@@ -13,13 +13,8 @@ namespace Bing.Elasticsearch.Tests
///
/// ES仓储测试
///
- public class EsRepositoryTest
+ public class EsRepositoryTest:EsTestBase
{
- ///
- /// 服务提供程序
- ///
- protected IServiceProvider ServiceProvider { get; }
-
private readonly List _students = new List
{
new StudentSample
@@ -60,28 +55,6 @@ public class EsRepositoryTest
}
};
- public EsRepositoryTest()
- {
- ServiceProvider = GetServiceProvider();
- }
-
- protected IServiceProvider GetServiceProvider()
- {
- var services = new ServiceCollection();
- services.AddElasticsearch(o =>
- {
- o.Urls = new List
- {
- "http://10.186.135.120:9200",
- "http://10.186.135.125:9200",
- "http://10.186.135.135:9200",
- };
- o.DefaultIndex = "bing_es_sample";
- o.Prefix = "bing_sample";
- });
- return services.BuildServiceProvider();
- }
-
[Fact]
public void Test_GetEsRepository()
{
diff --git a/tests/Bing.Elasticsearch.Tests/EsTestBase.cs b/tests/Bing.Elasticsearch.Tests/EsTestBase.cs
new file mode 100644
index 0000000..77f0930
--- /dev/null
+++ b/tests/Bing.Elasticsearch.Tests/EsTestBase.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Bing.Elasticsearch.Tests
+{
+ ///
+ /// ES测试基类
+ ///
+ public class EsTestBase
+ {
+ ///
+ /// 服务提供程序
+ ///
+ protected IServiceProvider ServiceProvider { get; }
+
+ public EsTestBase() => ServiceProvider = GetServiceProvider();
+
+ ///
+ /// 获取服务提供程序
+ ///
+ protected IServiceProvider GetServiceProvider()
+ {
+ var services = new ServiceCollection();
+ services.AddElasticsearch(o =>
+ {
+ o.Urls = new List
+ {
+ "http://10.186.103.244:9201",
+ "http://10.186.103.244:9202",
+ "http://10.186.103.244:9203",
+ };
+ o.DefaultIndex = "bing_es_sample";
+ o.Prefix = "bing_sample";
+ o.UserName = "elastic";
+ o.Password = "gzdevops2022";
+ o.NumberOfShards = 3;
+ o.NumberOfReplicas = 1;
+ });
+ return services.BuildServiceProvider();
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/Bing.Elasticsearch.Tests/Mapping/TestModel1Map.cs b/tests/Bing.Elasticsearch.Tests/Mapping/TestModel1Map.cs
new file mode 100644
index 0000000..09f6c38
--- /dev/null
+++ b/tests/Bing.Elasticsearch.Tests/Mapping/TestModel1Map.cs
@@ -0,0 +1,30 @@
+using System;
+using Bing.Elasticsearch.Mapping;
+using Bing.Elasticsearch.Options;
+using Bing.Elasticsearch.Tests.Models;
+using Nest;
+
+namespace Bing.Elasticsearch.Tests.Mapping
+{
+ public class TestModel1Map : ElasticMapping
+ {
+ ///
+ /// 初始化一个类型的实例
+ ///
+ /// 类型
+ /// ES选项配置
+ public TestModel1Map(Type type, ElasticsearchOptions options) : base(type, options)
+ {
+ }
+
+ ///
+ /// 配置索引映射
+ ///
+ /// 映射
+ public override TypeMappingDescriptor ConfigureIndexMapping(TypeMappingDescriptor map)
+ {
+ return map.AutoMap()
+ .Properties(p => p.Number(f => f.Name(e => e.Id).Type(NumberType.Long)));
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/Bing.Elasticsearch.Tests/Models/TestModel1.cs b/tests/Bing.Elasticsearch.Tests/Models/TestModel1.cs
new file mode 100644
index 0000000..93a9848
--- /dev/null
+++ b/tests/Bing.Elasticsearch.Tests/Models/TestModel1.cs
@@ -0,0 +1,50 @@
+using System;
+using Nest;
+
+namespace Bing.Elasticsearch.Tests.Models
+{
+ public class TestModel1
+ {
+ ///
+ /// 系统编号
+ ///
+ public long Id { get; set; }
+
+ ///
+ /// keyword 不分词
+ ///
+ [Keyword(Name = "Name", Index = true)]
+ public string Name { get; set; }
+
+ ///
+ /// text 分词,Analyzer = "ik_max_word"
+ ///
+ [Text(Name = "Test_Dic",Analyzer = "ik_max_word")]
+ public string Dic { get; set; }
+
+ ///
+ /// 状态
+ ///
+ public int State { get; set; }
+
+ ///
+ /// 逻辑删除
+ ///
+ public bool Deleted { get; set; }
+
+ ///
+ /// 创建时间
+ ///
+ public DateTime CreateTime { get; set; }
+
+ ///
+ /// float 值
+ ///
+ public float Fvalue { get; set; }
+
+ ///
+ /// double 值
+ ///
+ public double Dvalue { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/tests/Bing.Elasticsearch.Tests/Models/TestModel5.cs b/tests/Bing.Elasticsearch.Tests/Models/TestModel5.cs
index fb68890..27c6ece 100644
--- a/tests/Bing.Elasticsearch.Tests/Models/TestModel5.cs
+++ b/tests/Bing.Elasticsearch.Tests/Models/TestModel5.cs
@@ -12,25 +12,25 @@ public class TestModel5
///
/// 系统编号
///
- [Number(NumberType.Long,Name = "Id")]
+ [Number(NumberType.Long, Name = "Id")]
public long Id { get; set; }
///
/// keyword 不分词
///
- [Keyword(Name = "Name",Index = true)] // 不需要分词的字符串,name=名称,index=是否建立索引
+ [Keyword(Name = "Name", Index = true)] // 不需要分词的字符串,name=名称,index=是否建立索引
public string Name { get; set; }
///
/// text 分词,Analyzer = "ik_max_word"
///
- [Text(Name = "Dic",Index = true)] // 需要分词的字符串,name=名称,index=是否建立索引,Analyzer=分词器
+ [Text(Name = "Dic", Index = true, Analyzer = "ik_max_word")] // 需要分词的字符串,name=名称,index=是否建立索引,Analyzer=分词器
public string Dic { get; set; }
///
/// 状态
///
- [Number(NumberType.Integer,Name = "State")]// 数字类型+名称
+ [Number(NumberType.Integer, Name = "State")]// 数字类型+名称
public int State { get; set; }
///
@@ -48,13 +48,13 @@ public class TestModel5
///
/// float 值
///
- [Number(NumberType.Float,Name = "Fvalue")]
+ [Number(NumberType.Float, Name = "Fvalue")]
public float Fvalue { get; set; }
///
/// double 值
///
- [Number(NumberType.Double,Name = "Dvalue")]
+ [Number(NumberType.Double, Name = "Dvalue")]
public double Dvalue { get; set; }
}
}