.netcore 简单使用ElasticSearch(7.6)

最近在捣鼓学习了下ElasticSearch,在此记录下使用.netcore操作elastic search 的实现(简单的封装,使用)。需要注意的是不同版本的Elastic Search差异可能较大,需要对应版本去封装操作,例如6.x版本的支持1个index下多个Type,而7.x已经开始去掉了type概念,而且查询等操作中必须先指明indexname,否则报错。

项目需要添加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 }

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 }

---------用户密码验证(注释部分),可以配置在EsConfig中---------

 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 }

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

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 }

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 }

3、项目中注入和使用ElasticSearch

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 }

4、测试(略)

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

以上

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

.netcore 简单使用ElasticSearch的更多相关文章

  1. .NetCore简单学习图谱

    一.学习途径 学习.netcore的最佳途径在哪里,无疑是微软官方.netCore指南.它覆盖十分全面,就目前网上经常看到的各种文章都能在微软处找到类似文章,堪称.netcore的百科全书.所以我利用 ...

  2. ElasticSearch(五):简单的ElasticSearch搜索功能

    这里主要是一些简单的ElasticSearch的搜索功能,复杂的搜索,比如过滤,聚合等以后单独在写 1. 搜索全部 GET book/_search 直接搜索全部,下面是对搜索结果的详细介绍:默认情况 ...

  3. .NetCore简单封装基于IHttpClientFactory的HttpClient请求

    IHttpClientFactory是什么?为什么出现了IHttpClientFactory 一.IHttpClientFactory是什么? IHttpClientFactory是.netcore2 ...

  4. 简单操作elasticsearch(es版本7.6)

    简单操作elasticsearch(es版本7.6) es 官方文档 https://www.elastic.co/guide/index.html 简单操作elasticsearch主要是指管理索引 ...

  5. .netcore简单集成swagger

    为什么要集成Swagger 在前后端分离比较普遍的当下,当后端开发完接口后,还需把接口的信息.参数说明.返回参数等信息编写好提供给调用者.对于对外开放接口需提供说明文档是必不可少的.但是对于内部开发, ...

  6. Jmeter简单测试elasticsearch服务器

    入门知识: Jmeter是一个非常好用的压力测试工具.  Jmeter用来做轻量级的压力测试,非常合适,只需要十几分钟,就能把压力测试需要的脚本写好. 顾名思义:压力测试,就是  被测试的系统,在一定 ...

  7. 【elasticsearch】(2)centos7 超简单安装elasticsearch 的监控、测试的集群工具elasticsearch head

    elasticsearch-head是elasticsearch(下面称ES)比较普遍使用的可监控.测试等功能的集群管理工具,是由H5编写的单独的网页程序.使用方法网上很多,这里教大家一个超简单安装h ...

  8. 手写一个简单的ElasticSearch SQL转换器(一)

    一.前言 之前有个需求,是使ElasticSearch支持使用SQL进行简单查询,较新版本的ES已经支持该特性(不过貌似还是实验性质的?) ,而且git上也有elasticsearch-sql 插件, ...

  9. 【elasticsearch】(4)centos7 超简单安装elasticsearch 的 jdbc

    前言 elasticsearch(下面简称ES)使用jdbc连接mysql比go-mysql-elasticsearch的elasticsearch-river-jdbc能够很好的支持增量数据更新的问 ...

随机推荐

  1. 【题解】[USACO07NOV]Sunscreen G

    \(Link\) \(\text{Solution:}\) 把奶牛的忍耐度转化为线段,则题目转化为选择一些点使得覆盖的线段尽可能多.一个点只能覆盖一条线段. 考虑将点按照位置排序,线段按照右端点排序. ...

  2. winfrom加载自定义控件、窗口pannel后闪烁问题

    我用一个panel当容器,里面有好多控件,加载的时候一直闪烁. 借鉴网友的思路: 窗口初始化界面加入代码 this.DoubleBuffered = true;//设置本窗体   SetStyle(C ...

  3. AngularJS应用访问Android手机画廊

    下载angularjs.zip - 4.5 KB 介绍 本文演示了如何使用AngularJS调用Android应用程序公开的REST api来查看图库. 背景 Android和iOS都有相当多的远程访 ...

  4. 萌新学python

    python python安装 进入官网http://www.python.org/download/ 下载 我下的是3.6.6大家可以根据需要下载(3.x和2.x不兼容请小心) 之后安装就可以了 p ...

  5. Java 10 种常用第三方服务

    严格意义上说,所有软件的第三方服务都可以自己开发,不过从零到一是需要时间和金钱成本的.就像我们研发芯片,投入了巨大的成本,但仍然没有取得理想的成绩,有些事情并不是一朝一夕,投机取巧就能完成的. Jav ...

  6. javascript in IE

    前提:一个页面导入若干个js文件 问题: 1.如果其中一个文件出问题可能会导致下面的文件导入失败,如果导入很多外部js库文件,导致错误不好排查,可以调整好js的加载顺序,以免影响页面功能 2.IE获取 ...

  7. Unix中使用MeteoInfo - Xmanager设置

    通过Xshell等客户端登陆Unix系统运行图形软件(X11)需要有X-server,Xmanager是其中的佼佼者(可惜是商业软件).我通常用Xshell登陆气象局的IBM高性能计算机(AIX系统) ...

  8. 使用python编写正逆序乘法表

    # 99乘法表 # 顺序 for i in range(1,10): n = 1 while n <= i: print('{}x{}={}'.format(n,i,n*i),end=' ') ...

  9. go sync.WaitGroup

    package mainimport ( "fmt" "sync")func say(i int ,wg *sync.WaitGroup) { defer wg ...

  10. spring boot:用shardingjdbc实现多数据源的分库分表(shardingsphere 4.1.1/spring boot 2.3.1)

    一,shardingjdbc的用途 1,官方站介绍: Apache ShardingSphere 是一套开源的分布式数据库中间件解决方案组成的生态圈, 它由 JDBC.Proxy 和 Sidecar( ...