.Net Core中使用NEST简单操作Elasticsearch
C#中访问Elasticsearch主要通过两个包NEST和Elasticsearch.Net,NEST用高级语法糖封装了Elasticsearch.Net可以通过类Linq的方式进行操作,而Elasticsearch.Net相比之下更为原始直接非常自由。
注意:ES的8.X以上的版本有新的包Elastic.Clients.Elasticsearc支持。
此处使用NEST,我们通过Nuget安装,如下图:

1、准备结构
准备以下实体
public class Company
{
public string Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public User User { get; set; }
}
public class User
{
public string Name { get; set; }
public int Gender { get; set; }
}
2、连接ES
如果是单机连接如下代码,可以直接在Uri上指定账号密码,也可以使用ConnectionSettings的BasicAuthentication来配置账号密码:
var singleNode = new Uri("http://elastic:123456@localhost:9200");
var connSettings = new ConnectionSettings(singleNode);
//connSettings.BasicAuthentication("elastic", "123456");
var esClient = new ElasticClient(connSettings);
如果是多个节点集群则如下代码:
var nodes = new Uri[]
{
new Uri("http://esNode1:9200"),
new Uri("http://esNode2:9200"),
new Uri("http://esNode3:9200")
};
var pool = new StaticConnectionPool(nodes);
var settings = new ConnectionSettings(pool);
var client = new ElasticClient(settings);
3、创建索引
索引名称必须符合规则否则创建会失败,比如索引只能小写,具体代码如下:
var indexName = "my_index1";//索引名称
var res = await esClient.Indices.CreateAsync(indexName, o => o.Map(g => g.AutoMap<Company>()));//映射结构
也可以在向索引插入数据的时候自动判断是否存在索引,不存在会自动创建。索引结构字段映射一但创建就无法修改,可以通过新建索引然后转移数据的方式修改索引结构,但是可以往里面新增字段映射,比如修改了实体结构新的字段将会被映射。
4、插入数据
使用IndexDocumentAsync方法插入单条数据需要在ConnectionSettings的DefaultIndex方法设置默认索引。使用IndexAsync插入单条数据时需要选择指定索引,如下:
var singleNode = new Uri("http://localhost:9200");
var connSettings = new ConnectionSettings(singleNode);
connSettings.BasicAuthentication("elastic", "123456");
var esClient = new ElasticClient(connSettings.DefaultIndex("my_index1"));
var indexName = "my_index1";
var company = new Company()
{
Name = "超级公司bulk",
Description = "超级描述bulk",
};
var res1 = await esClient.IndexDocumentAsync(company);
var res2 = await esClient.IndexAsync(company, g => g.Index(indexName))
如果需要批量插入需要用BulkDescriptor对象包裹,然后使用BulkAsync方法插入,或者不要包裹直接用IndexManyAsync方法插入,具体如下:
var company = new Company()
{
Name = "超级公司bulk",
Description = "超级描述bulk"
});
BulkDescriptor descriptor = new BulkDescriptor();
descriptor.Index<Company>(op => op.Document(company).Index(indexName));
var res = await esClient.BulkAsync(descriptor);
//var list = new List<Company>();
//list.Add(company);
//var res = await esClient.IndexManyAsync(list, indexName);
如果实体有Id则会使用Id的值做为_id的索引文档唯一值,或者可以通过手动指定如await esClient.IndexAsync(company, g => g.Index(indexName).Id(company.Id)),如果id相同执行插入操作则为更新不会重复插入。在新增后是会返回id等信息可以加以利用。
5、删除数据
删除指定单条数据需要知道数据的id,如下两种方式:
DocumentPath<Company> deletePath = new DocumentPath<Company>(Guid.Empty);
var delRes = await esClient.DeleteAsync(deletePath, g => g.Index(indexName));
//或者
IDeleteRequest request = new DeleteRequest(indexName, "1231");
var delRes = await esClient.DeleteAsync(request);
多条删除使用DeleteByQueryAsync方法进行匹配删除,下面两种方式等价,删除Description字段模糊查询有描述的数据(最多10条):
var req = new DeleteByQueryRequest<Company>(indexName)
{
MaximumDocuments = 10,//一次最多删几条
Query = new MatchQuery()
{
Field = "description",
Query = "描述"
}
};
var result = await esClient.DeleteByQueryAsync(req);
//等价于
var result = await esClient.DeleteByQueryAsync<Company>(dq =>
dq.MaximumDocuments(10).Query(
q => q.Match(tr => tr.Field(fd => fd.Description).Query("描述"))).Index(indexName)
);
6、更新数据
除了上述插入数据时自动根据id进行更新外还有以下的主动更新。
根据id更新单条数据以下代码等价,可以更新部分字段值,但是_id是确定就不会更改的虽然对应的Id字段已被修改:
DocumentPath<Company> deletePath = new DocumentPath<Company>("1231");
var res = await esClient.UpdateAsync(deletePath ,(p) => p.Doc(company).Index(indexName));
//等价于
IUpdateRequest<Company, Company> request = new UpdateRequest<Company, Company>(indexName, "1231")
{
Doc = new Company()
{
Id = "888",
Description = "11111",
}
};
var res = await esClient.UpdateAsync(request);
如果有多个id更新多条数据可以用如下方法:
var res = esClient.Bulk(b => b.UpdateMany(new List<Company>() { new Company()
{
Id="1231",
} }, (b, u) => b.Id(u.Id).Index(indexName).Doc(new Company { Name = "我无语了" })));
通过条件批量更新如下,
var req = new UpdateByQueryRequest<Company>(indexName)
{
MaximumDocuments = 10,//一次最多更新几条
Query = new MatchQuery()
{
Field = "description",
Query = "66",
},
Script = new ScriptDescriptor()
.Source($"ctx._source.description = params.description;")
.Params(new Dictionary<string, object>
{
{ "description","小时了123123123"}
}),
Refresh = true
};
var result = await esClient.UpdateByQueryAsync(req);
7、数据查询
上文中的更新等都用到了查询过滤,此处就用网上的这个例子吧:
var result = client.Search<VendorPriceInfo>(
s => s
.Explain() //参数可以提供查询的更多详情。
.FielddataFields(fs => fs //对指定字段进行分析
.Field(p => p.vendorFullName)
.Field(p => p.cbName)
)
.From(0) //跳过的数据个数
.Size(50) //返回数据个数
.Query(q =>
q.Term(p => p.vendorID, 100) // 主要用于精确匹配哪些值,比如数字,日期,布尔值或 not_analyzed的字符串(未经分析的文本数据类型):
&&
q.Term(p => p.vendorName.Suffix("temp"), "姓名") //用于自定义属性的查询 (定义方法查看MappingDemo)
&&
q.Bool( //bool 查询
b => b
.Must(mt => mt //所有分句必须全部匹配,与 AND 相同
.TermRange(p => p.Field(f => f.priceID).GreaterThan("0").LessThan("1"))) //指定范围查找
.Should(sd => sd //至少有一个分句匹配,与 OR 相同
.Term(p => p.priceID, 32915),
sd => sd.Terms(t => t.Field(fd => fd.priceID).Terms(new[] {10, 20, 30})),//多值
//||
//sd.Term(p => p.priceID, 1001)
//||
//sd.Term(p => p.priceID, 1005)
sd => sd.TermRange(tr => tr.GreaterThan("10").LessThan("12").Field(f => f.vendorPrice))
)
.MustNot(mn => mn//所有分句都必须不匹配,与 NOT 相同
.Term(p => p.priceID, 1001)
,
mn => mn.Bool(
bb=>bb.Must(mt=>mt
.Match(mc=>mc.Field(fd=>fd.carName).Query("至尊"))
))
)
)
)//查询条件
.Sort(st => st.Ascending(asc => asc.vendorPrice))//排序
.Source(sc => sc.Include(ic => ic
.Fields(
fd => fd.vendorName,
fd => fd.vendorID,
fd => fd.priceID,
fd => fd.vendorPrice))) //返回特定的字段
);
.Net Core中使用NEST简单操作Elasticsearch的更多相关文章
- 简单操作elasticsearch(es版本7.6)
简单操作elasticsearch(es版本7.6) es 官方文档 https://www.elastic.co/guide/index.html 简单操作elasticsearch主要是指管理索引 ...
- elk快速入门-在kibana中如何使用devtools操作elasticsearch
在kibana中如何使用devtools操作elasticsearch:前言: 首先需要安装elasticsearch,kibana ,下载地址 https://www.elastic.co/cn/d ...
- python中通过selenium简单操作及xpath元素定位&轴定位
浏览器的简单操作 # 导入webdriver模块 # 创建driver对象,指定Chrome浏览器 driver = webdriver.Chrome() # 窗口最大化 driver.maximiz ...
- 关于js中select的简单操作,以及js前台计算,span简单操作
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- .NET Core 中的 Logging 简单实用 - 记录日志消息显示到控制台
.NET Core 支持适用于各种内置和第三方日志记录提供程序的日志记录 API. 本文介绍了如何将日志记录 API 与内置提供程序一起使用. 本文中所述的大多数代码示例都来自 .Net 5 应用. ...
- Linux中的定时任务简单操作实例
今天,我怀着一颗感恩的心,写了一个小小的定时任务,细想还是写个简单的例子吧,希望能帮到你! 首先我在/usr/local/文件夹下创建了一个文件,hah.sh文件 在hah.sh里面编写shell脚本 ...
- jQuery中cookie的简单操作
jQuery 可以通过 jquery.cookie.js 插件来操作 Cookie. 用NuGet安装:PM>Install-Package js-cookie -Version 官网:http ...
- Asp.net core中RedisMQ的简单应用
最近一个外部的项目,使用到了消息队列,本来是用rabbitmq实现的,但是由于是部署到别人家的服务器上,想尽量简化一些,项目中本来也要接入了redis缓存,就尝试使用redis来实现简单的消息队列. ...
- django中orm的简单操作
数据库模型 from django.db import models # Create your models here. from django.db import models # Create ...
- asp .net core中swagger的简单使用
相信swagger大家不太陌生,简单来说就是把web api接口以ui的形式呈现到页面上,供方便调用和展示.这边文章就带大家初步简单使用swagger. (1)首先需要安装包:Swashbuckle. ...
随机推荐
- Git基操记录
小结 说多了都是泪,最近在整理Java的笔记,记笔记我比较喜欢使用markdown(当时使用Hexo的原因之一),毕竟作为刚入门槛一点点的程序小白,还没用上Idea(很多大佬都推荐这个),目前还在使用 ...
- 关于pip3 ImportError: cannot import name 'main'的报错的原因及解决办法
这个问题的出现大多数都是因为你用错误的方法去升级pip3导致的 先来说一下正确的升级方法: python3 -m pip install --upgrade pip 我发现升级后版本变为了 19.x, ...
- 移动 VR 开发时要避免的 PC 渲染技术
更新:本文是为 Quest 1 开发人员编写的.虽然 Quest 2 建立在相同的架构上,但现在更容易为阴影贴图(以及其他需要从先前渲染过程中生成的纹理读取的简单技术)做预算. 尽管移动芯片组可以支持 ...
- thinkphp6文件上传自定义命名规则
think官方自带的命名规则有三种 规则 描述 date 根据日期和微秒数生成 md5 对文件使用md5_file散列生成 sha1 对文件使用sha1_file散列生成 其中md5和sha1规则会自 ...
- TKE 超级节点,Serverless 落地的最佳形态
陈冰心,腾讯云产品经理,负责超级节点迭代与客户拓展,专注于 TKE Serverless 产品演进. 背景 让人又爱又恨的 Serverless Serverless 炙手可热,被称为云原生未来发展的 ...
- 【微服务架构设计实施】第一部分:架构篇-1:微服务架构与Spring Cloud介绍
〇.概述 一.微服务架构与Spring Cloud (一)概念 不同说法:细粒度的.清凉组件化的小型SOA(面向服务架构) 统一说法:小型应用程序(服务组件),使用轻量级设计方法和HTTP协议通信 理 ...
- @Transactional注解事务失效的几种场景及原因
1. 介紹 在业务开发的许多场景中,我们会使用到通过事务去控制多个操作的一致性.比较多的就是通过声明式事务,即使用 @Transactional 注解修饰方法的形式.但在使用过程中,要足够了解事务失效 ...
- Velero 系列文章(一):基础
概述 Velero 是一个开源工具,可以安全地备份和还原,执行灾难恢复以及迁移 Kubernetes 集群资源和持久卷. 灾难恢复 Velero 可以在基础架构丢失,数据损坏和/或服务中断的情况下,减 ...
- 模板层之标签 自定义过滤器及标签 模板的继承与导入 模型层之前期准备 ORM常用关键字
目录 模板层之标签 if判断 for循环 自定义过滤器.标签及inclusion_tag(了解) 前期三步骤 自定义过滤器(最大只能接收两个参数) 自定义标签(参数没有限制) 自定义inclusion ...
- 基于.NetCore开发博客项目 StarBlog - (21) 开始开发RESTFul接口
前言 最近电脑坏了,开源项目的进度也受到一些影响 这篇酝酿很久了,作为本系列第二部分(API接口开发)的第一篇,得想一个好的开头,想着想着就鸽了好久,索性不扯那么多了,直接开写吧~ 关于RESTFul ...