.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. 大话Python函数底层逻辑

    函数 叫 子过程或子程序 描叙的更为贴近实际应用场景 这和数学中的函数实现上不同但语义上相识,如 f(x) = expressiom, 给定一个确定的输入必然返回一个确定的输出 数学中函数的关系是通过 ...

  2. IntelliJ IDEA 调试 Java 8 Stream,实在太香了!

    前段时间,栈长发布了一篇关于 Java 8 Optional.map 的实用文章,留言区就有的人说 Java 8 的语法糖不方便调试,还要视情况使用. 留言区也有人说 IntelliJ IDEA 早已 ...

  3. Oracle 数据库创建表空间、创建用户

    创建表空间 create temporary tablespace user_name_temp tempfile '/oradata/ORA11G/user_name_temp.dbf' size ...

  4. 微信小程序tabbar不显示2019.04.06

    app.json中pages的第一项必须在tabBar中,且这一项需要在pages的list中(与顺序无关)否则无法显示tabBar app.json中pages数组中第一项(首页),必须在tabBa ...

  5. day23 Pyhton学习 昨日回顾.re模块.序列化模块

    一.昨日回顾 #__file__查看当前文件所在的绝对路径 #time 时间模块 time.time 获取当前时间戳时间 字符串->time.strptime->结构化->mktim ...

  6. docker-搭建单机 kafka+zookeeper

    1 zookeeper   docker run --name zookeeper -p 12181:2181 -d wurstmeister/zookeeper:latest   2 kafka   ...

  7. 如何使用 Gin 和 Gorm 搭建一个简单的 API 服务 (一)

    介绍   Go 语言最近十分火热,但对于新手来说,想立马上手全新的语法和各种各样的框架还是有点难度的.即使是基础学习也很有挺有挑战性.   在这篇文章中,我想用最少的代码写出一个可用的 API 服务. ...

  8. 因果推理综述——《A Survey on Causal Inference》一文的总结和梳理

    因果推理 本文档是对<A Survey on Causal Inference>一文的总结和梳理. 论文地址 简介 关联与因果 先有的鸡,还是先有的蛋?这里研究的是因果关系,因果关系与普通 ...

  9. C# 将Excel里面的数据填充到DataSet中

    /// <summary> /// 将Excel表里的数据填充到DataSet中 /// </summary> /// <param name="filenam ...

  10. Linux入门到放弃之八《任务计划管理》

    任务计划管理 1.每周一下午5:50将/data目录下的所有目录和文件归档并压缩为:backup.tar.gz 放在/home/backup目录下. 先新建/data目录,并在目录中随意生成几个文件 ...