最近在搗鼓學習了下ElasticSearch,在此記錄下使用.netcore操做elastic search 的實現(簡單的封裝,使用)。須要注意的是不一樣版本的Elastic Search差別可能較大,須要對應版本去封裝操做,例如6.x版本的支持1個index下多個Type,而7.x已經開始去掉了type概念,並且查詢等操做中必須先指明indexname,不然報錯。html
項目須要添加Elasticsearch.Net和Nestapi
相關文檔地址elasticsearch
Elasticsearch文檔:https://www.elastic.co/guide/en/elasticsearch/reference/current/index.htmlide
Elasticsearch.Net和Nest官方文檔:https://www.elastic.co/guide/en/elasticsearch/client/net-api/7.x/index.html學習
1)建立ElasticSearch配置類測試
1 public class EsConfig : IOptions<EsConfig> 2 { 3 public List<string> Urls { get; set; } 4 5 public EsConfig Value => this; 6 }
2)創ElasticSearch提供者接口以及類ui
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 }
---------用戶密碼驗證(註釋部分),能夠配置在EsConfig中---------this
1 /// <summary> 2 /// 根據urls獲取ElasticClient 3 /// </summary> 4 /// <param name="urls"></param> 5 /// <param name="defaultIndex"></param> 6 /// <returns></returns> 7 public ElasticClient GetClient(string[] urls, string defaultIndex = "") 8 { 9 if (urls == null || urls.Length < 1) 10 { 11 throw new Exception("urls can not be null"); 12 } 13 var uris = urls.Select(p => new Uri(p)).ToArray(); 14 var connectionPool = new SniffingConnectionPool(uris); 15 var connectionSetting = new ConnectionSettings(connectionPool); 16 if (!string.IsNullOrWhiteSpace(defaultIndex)) 17 { 18 connectionSetting.DefaultIndex(defaultIndex); 19 } 20 //connectionSetting.BasicAuthentication("", ""); //設置帳號密碼 21 return new ElasticClient(connectionSetting); 22 }
-------------------url
1)、擴展ElasticClient類.net
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 }
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 }
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 }
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 }
1)、配置文件
1 "EsConfig": { 2 "ConnectionStrings": [ "http://127.0.0.1:9200/" ] 3 }
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 );
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 }
-------------------------------------
以上
固然es還有不少操做的,聚合查詢、不一樣條件的查詢(範圍查詢、匹配查詢等等)、分詞等。具體能夠去查看其官方文檔對應實現!