.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. Hyper-V Server + Windows Admin Center

    2020年的十一黄金周是双节,偶然间得知再出现双节可能要几十年之后了,很可惜我并没有出去游玩的打算.所以假期没什么事,就来研究下Hyper Server + Windows Admin Center. ...

  2. C++中union的使用方法

    转载:https://blog.csdn.net/hou09tian/article/details/80816445 1 概述 1.1 定义 union即为联合,它是一种特殊的类.通过关键字unio ...

  3. #ifndef, #define, #endif三者的作用

    #ifndef, #define, #endif 作用   #ifndef 它是if not define 的简写,是宏定义的一种,实际上确切的说,这应该是预处理功能三种(宏定义.文件包含.条件编译) ...

  4. Splay浅谈

    Splay是众多平衡树之一,它的功能十分强大,但常数极大.在LCT和许多数据结构中都能用到. Splay的核心操作,就是rotate.为了使树不是一条链,而是平衡的,我们需要旋转来维护形态.理论很简单 ...

  5. MySQL计算月份间隔的函数

    要求忽视具体日期,即 2020-01-31 与 2020-02-01 的月份间隔为:1 -- 格式必须为: '%Y%m' SELECT PERIOD_DIFF("202008" , ...

  6. 第一次使用HSDB

    今天看了几篇大佬关于HSDB使用的文章,自己也依样画葫芦的用来一下,强大的一匹!!! HSDB(Hotspot Debugger),JDK自带的工具,用于查看JVM运行时的状态. HSDB位于C:\P ...

  7. Nginx 配置 http 强制跳转到 https

    个人真实配置 架构:Nginx 反向代理 + Nginx 前端(LNMP) 在 Nginx 反向代理的 虚拟机主机配置文件中,作如下配置: upstream ilexa_cn { server 192 ...

  8. 使用docker搭建redis服务器记录

    #mkdir /home/redishome#mkdir /home/redishome/data#chmod -R 777 /home/redishome把redis.conf传到/home/red ...

  9. 【博弈论】51Nod 1534 棋子游戏

    题目内容 波雷卡普和瓦西里喜欢简单的逻辑游戏.今天他们玩了一个游戏,这个游戏在一个很大的棋盘上进行,他们每个人有一个棋子.他们轮流移动自己的棋子,波雷卡普先开始.每一步移动中,波雷卡普可以将他的棋子从 ...

  10. centos8用firewalld搭建防火墙

    一,firewalld的systemd管理命令 启动:systemctl start firewalld 关闭:systemctl stop firewalld 查看状态:systemctl stat ...