.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. spring-boot-route(三)实现多文件上传

    Spring Boot默认上传的单个文件大小1MB,一次上传的总文件大小为10MB. 单个文件上传使用MultipartFile参数来接收文件,多文件使用MultipartFile[]数组来接收,然后 ...

  2. 012 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 06 浮点型“字面值”

    012 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 06 浮点型"字面值" 浮点型字面值 首先要知道一点:在整型部分中,默认情况下,即整型数 ...

  3. 05 sublime环境配置及编译运行后输出中文乱码的解决

    编译后的乱码问题 编译后的输出:中文显示异常: 编译C出现乱码问题解决 解决思路:解决办法很简单,就是先设置文件编码为GBK格式,之后再输入中文文字,运行时的中文就不是乱码了. 首先,sublime中 ...

  4. nessus 家庭版安装教程(windows)

    1.根据系统选择安装包:https://www.tenable.com/products/nessus/select-your-operating-system 2.申请激活码,在我们安装的时候差不多 ...

  5. Activity的常用控件

    TimerPick(时间控件)public Integer getCurrentHour() //返回当前设置的小时public Integer getCurrentMinute()//返回当前设置的 ...

  6. 阅读源码,从ArrayList开始

    前言 为啥要阅读源码?一句话,为了写出更好的程序. 一方面,只有了解了代码的执行过程,我们才能更好的使用别人提供的工具和框架,写出高效的程序.另一方面,一些经典的代码背后蕴藏的思想和技巧很值得学习,通 ...

  7. 回炉重造系列-C# func and action委托是什么?

    如题: C# func and action委托是什么? 1) 回答这个问题之前,我们需要了解什么是委托(英文 Delegate )? 为了便于理解,再往前推一步,回到c语言时代,指针的概念. 什么是 ...

  8. 【暑假集训】HZOI2019 水站 多种解法

    题目内容 已知有一个\(n\)层的水站: \(W_i\)表示未操作之前第\(i\)层的已有水量: \(L_i\)表示第\(i\)个水站能够维持或者储存的水的重量: 表示在第\(P_i\)层进行减压放水 ...

  9. 【原创】xenomai内核解析--xenomai与普通linux进程之间通讯XDDP(一)--实时端socket创建流程

    版权声明:本文为本文为博主原创文章,转载请注明出处.如有问题,欢迎指正.博客地址:https://www.cnblogs.com/wsg1100/ 1.概述 上篇文章xenomai内核解析--实时IP ...

  10. 《Kafka笔记》1、Kafka初识

    目录 一.初识Kafka 1 apache kafka简介 2 消息中间件kafka的使用场景 2.1 订阅与发布队列 2.2 流处理 3 kafka对数据的管理形式 4 kafka基础架构 5 Ka ...