.netcore 简单使用ElasticSearch

.netcore 简单使用ElasticSearch(7.6)

最近在捣鼓学习了下ElasticSearch,在此记录下使用.netcore操作elastic search 的实现(简单的封装,使用)

项目需要添加Elasticsearch.NetNest

相关文档地址

Elasticsearch文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html

Elasticsearch.Net和Nest官方文档:https://www.elastic.co/guide/en/elasticsearch/client/net-api/7.x/index.html

1、封装ElasticClient提供者

1)创建ElasticSearch配置类

1  public class EsConfig : IOptions<EsConfig>
2     {
3         public List<string> Urls { get; set; }
4 
5         public EsConfig Value => this;
6     }
View Code

2)创建ElasticSearch提供者接口以及类

 1     /// <summary>
 2     /// ElasticClient 提供者接口
 3     /// </summary>
 4     public interface IEsClientProvider
 5     {
 6         /// <summary>
 7         /// 获取ElasticClient
 8         /// </summary>
 9         /// <returns></returns> 
10         ElasticClient GetClient();
11         /// <summary>
12         /// 指定index获取ElasticClient
13         /// </summary>
14         /// <param name="indexName"></param>
15         /// <returns></returns>
16         ElasticClient GetClient(string indexName);
17     }
18 
19 
20 
21     /// <summary>
22     /// ElasticClient提供者
23     /// </summary>
24     public class EsClientProvider : IEsClientProvider
25     {
26         private readonly IOptions<EsConfig> _EsConfig;
27         public EsClientProvider(IOptions<EsConfig> esConfig)
28         {
29             _EsConfig = esConfig;
30         }
31         /// <summary>
32         /// 获取elastic client  
33         /// </summary>
34         /// <returns></returns> 
35         public ElasticClient GetClient()
36         {
37             if (_EsConfig == null || _EsConfig.Value == null || _EsConfig.Value.Urls == null || _EsConfig.Value.Urls.Count < 1)
38             {
39                 throw new Exception("urls can not be null");
40             }
41             return GetClient(_EsConfig.Value.Urls.ToArray(), "");
42         }
43         /// <summary>
44         /// 指定index获取ElasticClient
45         /// </summary>
46         /// <param name="indexName"></param>
47         /// <returns></returns>
48         public ElasticClient GetClient(string indexName)
49         {
50             if (_EsConfig == null || _EsConfig.Value == null || _EsConfig.Value.Urls == null || _EsConfig.Value.Urls.Count < 1)
51             {
52                 throw new Exception("urls can not be null");
53             }
54             return GetClient(_EsConfig.Value.Urls.ToArray(), indexName);
55         }
56 
57 
58         /// <summary>
59         /// 根据url获取ElasticClient
60         /// </summary>
61         /// <param name="url"></param>
62         /// <param name="defaultIndex"></param>
63         /// <returns></returns>
64         private ElasticClient GetClient(string url, string defaultIndex = "")
65         {
66             if (string.IsNullOrWhiteSpace(url))
67             {
68                 throw new Exception("es 地址不可为空");
69             }
70             var uri = new Uri(url);
71             var connectionSetting = new ConnectionSettings(uri);
72             if (!string.IsNullOrWhiteSpace(url))
73             {
74                 connectionSetting.DefaultIndex(defaultIndex);
75             }
76             return new ElasticClient(connectionSetting);
77         }
78         /// <summary>
79         /// 根据urls获取ElasticClient
80         /// </summary>
81         /// <param name="urls"></param>
82         /// <param name="defaultIndex"></param>
83         /// <returns></returns>
84         private ElasticClient GetClient(string[] urls, string defaultIndex = "")
85         {
86             if (urls == null || urls.Length < 1)
87             {
88                 throw new Exception("urls can not be null");
89             }
90             var uris = urls.Select(p => new Uri(p)).ToArray();
91             var connectionPool = new SniffingConnectionPool(uris);
92             var connectionSetting = new ConnectionSettings(connectionPool);
93             if (!string.IsNullOrWhiteSpace(defaultIndex))
94             {
95                 connectionSetting.DefaultIndex(defaultIndex);
96             }
97             return new ElasticClient(connectionSetting);
98         }
99     }
View Code

2、封装操作ElasticSearch实现

1)、扩展ElasticClient类

 1     /// <summary>
 2     /// ElasticClient 扩展类
 3     /// </summary>
 4     public static class ElasticClientExtension
 5     {
 6         /// <summary>
 7         /// 创建索引
 8         /// </summary>
 9         /// <typeparam name="T"></typeparam>
10         /// <param name="elasticClient"></param>
11         /// <param name="indexName"></param>
12         /// <param name="numberOfShards"></param>
13         /// <param name="numberOfReplicas"></param>
14         /// <returns></returns>
15         public static bool CreateIndex<T>(this ElasticClient elasticClient, string indexName = "", int numberOfShards = 5, int numberOfReplicas = 1) where T : class
16         {
17             
18             if (string.IsNullOrWhiteSpace(indexName))
19             {
20                 indexName = typeof(T).Name;
21             }
22              
23             if (elasticClient.Indices.Exists(indexName).Exists)
24             {
25                 return false;
26             }
27             else
28             {
29                 var indexState = new IndexState()
30                 {
31                     Settings = new IndexSettings()
32                     {
33                         NumberOfReplicas = numberOfReplicas,
34                         NumberOfShards = numberOfShards,
35                     },
36                 };
37                 var response = elasticClient.Indices.Create(indexName, p => p.InitializeUsing(indexState).Map<T>(p => p.AutoMap()));
38                 return response.Acknowledged;
39             }
40         }
41     }
View Code

2)、创建ElasticSearch操作基类

 1     /// <summary>
 2     /// 接口限定
 3     /// </summary>
 4     public interface IBaseEsContext { }
 5     /// <summary>
 6     /// es操作积累
 7     /// </summary>
 8     /// <typeparam name="T"></typeparam>
 9     public abstract class BaseEsContext<T> : IBaseEsContext where T : class
10     {
11         protected IEsClientProvider _EsClientProvider;
12         public abstract string IndexName { get;  }
13         public BaseEsContext(IEsClientProvider provider)
14         {
15             _EsClientProvider = provider;
16         }
17 
18         /// <summary>
19         /// 批量更新
20         /// </summary>
21         /// <param name="tList"></param>
22         /// <returns></returns>
23         public bool InsertMany(List<T> tList)
24         {
25             var client = _EsClientProvider.GetClient(IndexName);
26             if (!client.Indices.Exists(IndexName).Exists)
27             {
28                 client.CreateIndex<T>(IndexName);
29             }
30             var response = client.IndexMany(tList);
31             //var response = client.Bulk(p=>p.Index(IndexName).IndexMany(tList));
32             return response.IsValid;
33         }
34 
35         /// <summary>
36         /// 获取总数
37         /// </summary>
38         /// <returns></returns>
39         public long GetTotalCount()
40         {
41             var client = _EsClientProvider.GetClient(IndexName);
42             var search = new SearchDescriptor<T>().MatchAll(); //指定查询字段 .Source(p => p.Includes(x => x.Field("Id")));
43             var response = client.Search<T>(search);
44             return response.Total;
45         }
46         /// <summary>
47         /// 根据Id删除数据
48         /// </summary>
49         /// <returns></returns>
50         public bool DeleteById(string id)
51         {
52             var client = _EsClientProvider.GetClient(IndexName);
53             var response = client.Delete<T>(id);
54             return response.IsValid;
55         }
56 
57     }
View Code

3)、具体操作类(示例)

 1     /// <summary>
 2     /// 地址操作类
 3     /// </summary>
 4     public class AddressContext : BaseEsContext<Address>
 5     {
 6         /// <summary>
 7         /// 索引名称
 8         /// </summary>
 9         public override string IndexName => "address";
10         public AddressContext(IEsClientProvider provider) : base(provider)
11         {
12         }
13         /// <summary>
14         /// 获取地址
15         /// </summary>
16         /// <param name="province"></param>
17         /// <param name="pageIndex"></param>
18         /// <param name="pageSize"></param>
19         /// <returns></returns>
20         public List<Address> GetAddresses(string province, int pageIndex, int pageSize)
21         {
22             var client = _EsClientProvider.GetClient(IndexName);
23             var musts = new List<Func<QueryContainerDescriptor<Address>, QueryContainer>>();
24             musts.Add(p => p.Term(m => m.Field(x=>x.Pronvince).Value(province)));
25             var search = new SearchDescriptor<Address>();
26            // search = search.Index(IndexName).Query(p => p.Bool(m => m.Must(musts))).From((pageIndex - 1) * pageSize).Take(pageSize);
27             search =search.Query(p => p.Bool(m => m.Must(musts))).From((pageIndex - 1) * pageSize).Take(pageSize);
28             var response = client.Search<Address>(search);
29             return response.Documents.ToList();
30         }
31         /// <summary>
32         /// 获取所有地址
33         /// </summary>
34         /// <returns></returns>
35         public List<Address> GetAllAddresses()
36         { 
37             var client = _EsClientProvider.GetClient(IndexName);  
38             var searchDescriptor = new SearchDescriptor<Address>();
39             // searchDescriptor = searchDescriptor.Index(IndexName).Query(p => p.MatchAll());
40             searchDescriptor = searchDescriptor.Query(p => p.MatchAll());
41             var response = client.Search<Address>(searchDescriptor);
42             return response.Documents.ToList();
43         } 
44         /// <summary>
45         /// 删除指定城市的数据
46         /// </summary>
47         /// <param name="city"></param>
48         /// <returns></returns>
49         public bool DeleteByQuery(string city)
50         {
51             var client = _EsClientProvider.GetClient(IndexName);
52             var musts = new  List<Func<QueryContainerDescriptor<Address>, QueryContainer>>();
53             musts.Add(p=>p.Term(m=>m.Field(f=>f.City).Value(city)));
54             var search = new DeleteByQueryDescriptor<Address>().Index(IndexName);
55             search = search.Query(p => p.Bool(m => m.Must(musts)));
56             var response = client.DeleteByQuery<Address>(p=>search);
57             return response.IsValid;
58         }
59 
60     }
View Code

 address类

 1     [ElasticsearchType(IdProperty = "Id")]
 2     public class Address
 3     {
 4         [Keyword]
 5         public string Id { get; set; }
 6         [Keyword]
 7         public string Country { get; set; }
 8         [Keyword]
 9         public string City { get; set; }
10         [Keyword]
11         public string Pronvince { get; set; }
12         [Keyword]
13         public string Area { get; set; }
14         [Text]
15         public string Address1 { get; set; }
16 
17     }
View Code

3、项目中注入和使用ElasticSearch

1)、配置文件

1   "EsConfig": {
2     "ConnectionStrings": [ "http://127.0.0.1:9200/" ] 
3   }
View Code

2)、注入ElasticSearch

 1    services.Configure<EsConfig>(options =>
 2           {
 3               options.Urls = Configuration.GetSection("EsConfig:ConnectionStrings").GetChildren().ToList().Select(p => p.Value).ToList();
 4 
 5           });
 6 
 7 
 8             services.AddSingleton<IEsClientProvider, EsClientProvider>();
 9             var types = Assembly.Load("John.DotNetCoreStudy.EsCommon").GetTypes().Where(p => !p.IsAbstract && (p.GetInterfaces().Any(i => i == typeof(IBaseEsContext)))).ToList();
10             types.ForEach(p =>
11                     services.AddTransient(p)
12                 );
View Code

3)、Controller类中使用

 1     [Route("api/[controller]")]
 2     [ApiController]
 3     public class AddressController : ControllerBase
 4     {
 5         private AddressContext _AddressContext;
 6         public AddressController(AddressContext context)
 7         {
 8             _AddressContext = context;
 9         }
10         /// <summary>
11         /// 新增或者修改
12         /// </summary>
13         /// <param name="address"></param>
14         [HttpPost("添加地址")]
15         public void AddAddress(List<Address> addressList)
16         {
17             if (addressList == null || addressList.Count < 1)
18             {
19                 return;
20             }
21             _AddressContext.InsertMany(addressList);
22         }
23 
24         /// <summary>
25         /// 删除地址
26         /// </summary>
27         /// <param name="id"></param>
28         [HttpPost("deleteAddress")]
29         public void DeleteAdress(string id)
30         {
31             _AddressContext.DeleteById(id);
32         }
33         /// <summary>
34         /// 获取所有与地址
35         /// </summary>
36         /// <returns></returns>
37         [HttpGet("getAllAddress")]
38         public List<Address> GetAllAddress()
39         {
40             return _AddressContext.GetAllAddresses();
41         }
42         /// <summary>
43         /// 获取地址总数
44         /// </summary>
45         /// <returns></returns>
46         [HttpGet("getAddressTotalCount")]
47         public long GetAddressTotalCount()
48         {
49             return _AddressContext.GetTotalCount();
50         }
51        
52         /// <summary>
53         /// 分页获取(可以进一步封装查询条件)
54         /// </summary>
55         /// <param name="province"></param>
56         /// <param name="pageIndex"></param>
57         /// <param name="pageSize"></param>
58         /// <returns></returns>
59         [HttpPost("getAddressByProvince")]
60         public List<Address> GetAddressByProvince(string province,int pageIndex,int pageSize)
61         {
62             return _AddressContext.GetAddresses(province,pageIndex,pageSize);
63         }
64 
65     }
View Code

4、测试(略)

-------------------------------------

以上

当然es还有很多操作的,聚合查询、不同条件的查询(范围查询、匹配查询等等)、分词等。具体可以去查看其官方文档对应实现!

猜你喜欢

转载自www.cnblogs.com/johnyong/p/12906370.html