Elastcisearch.Nest 7.x 系列`伪`官方翻译:通过 NEST 来快捷试用 Elasticsearch
- 本系列已经全部完成,完整版可见 :https://blog.zhuliang.ltd/categories/Elasticsearch/
- 本系列博文是“伪”官方文档翻译(更加本土化),并非完全将官方文档进行翻译,而是在查阅、测试原始文档并转换为自己真知灼见后的“准”翻译。有不同见解 / 说明不周的地方,还请海涵、不吝拍砖 :)
- 官方文档见此:https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/introduction.html
- 本系列对应的版本环境:ElasticSearch@7.3.1,NEST@7.3.1,IDE 和开发平台默认为 VS2019,.NET CORE 2.1
Elasticsearch.Net 和 NEST 对比说明:
- Elasticsearch 官方为 .NET 提供了 2 个官方客户端库:Elasticsearch.Net 和 NEST。
- 可以简单理解为 Elasticsearch.Net 是 NEST 的一个子集。
- NEST 内部使用了 ElasticSearch.Net ,并通过 NEST 可以对外暴露 ElasticSearch.Net 客户端。
- 但 NEST 包含了 ElasticSearch.Net 所没有的一些高级功能,如:
- 强类型查询 DSL:可以将所有请求和响应的对象类型转换 1:1 的.NET 类型。
- 自动转换为 CLR 的数据类型。
基本上 .NET 项目到了要使用上 ElasticSearch 的地步,直接选择 NEST 即可。
在使用 NEST 作为客户端的时候,建议将 ElasticClient 对象作为单例来使用。
- ElasticClient 被设计为线程安全。
- ES 中的缓存是根据 ConnectionSettings 来划分的,即服务端缓存针对的是每一个 ConnectionStrings
- 例外: 当你需要连接不同的 ES 集群的时候,就不要用单例了,应为不同的 ElasticClient 使用不同的 ConnectionStrings。
快速使用
- 使用 Nest 的时候约定 Nest 版本需要跟 ElasticSearch 版本保持一致,即服务端 ES版本为 7.3.1,则 Nest 版本也要使用 7.3.1
- 以下示例通过 IoC 进行注入(单例),你也可以直接通过单例模式来实现。
配置、连接 ElasticSearch
配置类:
public class ElasticSearchSettings
{
public string ServerUri { get; set; }
public string DefaultIndex { get; set; } = "defaultindex";
}
ElasticSearch 客户端:
- 连接到 ElasticSearch,并设定默认索引
public class ElasticSearchClient : IElasticSearchRepository
{
private readonly ElasticSearchSettings _esSettings;
private readonly ElasticClient _client;
public ElasticSearchClient(IOptions<ElasticSearchSettings> esSettings)
{
_esSettings = esSettings.Value;
var settings = new ConnectionSettings(new Uri(_esSettings.ServerUri)).DefaultIndex(_esSettings.DefaultIndex);
_client = new ElasticClient(settings);
}
public ElasticSearchClient(ElasticSearchSettings esSettings)
{
_esSettings = esSettings;
var settings = new ConnectionSettings(new Uri(_esSettings.ServerUri)).DefaultIndex(_esSettings.DefaultIndex);
_client = new ElasticClient(settings);
}
}
- 建议增加默认索引名,不然在请求时推断索引名的时候可能会引发异常,更多关于索引名的推断见此博文NEST 教程系列 9-1 转换:Index name inference | 索引名推断的3种方式
连接配置上使用密码凭证
ElasticSearch 可以直接在 Uri 上指定密码,如下:
var uri = new Uri("http://username:password@localhost:9200")
var settings = new ConnectionConfiguration(uri);
- 但不建议这么做,尤其是在多个节点的连接池或者能够 reseeding 的连接池上的时候。
- **建议使用 ConnectionSettings 来设定凭证。NEST 教程系列 2-4 连接:Working with certificates | 使用凭证连接
使用连接池
ConnectionSettings 不仅支持单地址的连接方式,同样提供了不同类型的连接池来让你配置客户端,如使用 SniffingConnectionPool 来连接集群中的 3 个 Elasticsearch 节点,客户端将使用该类型的连接池来维护集群中的可用节点列表,并会以循环的方式发送调用请求。
var uris = new[]{
new Uri("http://localhost:9200"),
new Uri("http://localhost:9201"),
new Uri("http://localhost:9202"),};
var connectionPool = new SniffingConnectionPool(uris);var settings = new ConnectionSettings(connectionPool)
.DefaultIndex("people");
_client = new ElasticClient(settings);
NEST 教程系列 2-1 连接:Configuration options| 配置选项
索引(Indexing)
- 这里的“索引”需理解为动词,用 indexing 来理解会更好,表示将一份文档插入到 ES 中。
假设有如下类 User.cs
public class User
{
public Guid Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
索引(Indexing)/添加 一份文档到 ES 中
//同步
var response = _client.IndexDocument<User>(new User
{
Id = new Guid("3a351ea1-bfc3-43df-ae12-9c89e22af144"),
FirstName = "f1",
LastName = "l1"
});
//异步
var response = _client.IndexDocumentAsync<User>(new User
{
Id = new Guid("82f323e3-b5ec-486b-ac88-1bc5e47ec643"),
FirstName = "f2",
LastName = "l2"
});
- 目前提供的方法基本上都含有同步和异步版本(异步方法以 *Async 结尾)
- IndexDocument 方法会判断添加的文档是否已经存在(根据 _id),若存在,则添加失败。
- NEST 会自动将 Id 属性作为 ES 中的 _id,更多关于 id 的推断方式见此博文:NEST 教程系列 9-3 转换:Id 推断
- 默认情况下,会使用 camel 命名方式进行转换,你可以使用 ConnectionSettings 对象的 .DefaultFieldNameInferrer(Func<string, string>) 方法来调整默认转换行为,更多关于属性的推断的见此博文:NEST 教程系列 9-4 转换:Field 属性推断
最终请求地址为:
PUT /users/_doc/3a351ea1-bfc3-43df-ae12-9c89e22af144
查询
通过类 lambda 表达式进行查询
通过 Search 方法进行查询。
var result = _client.Search<User>(s=>s.From(0)
.Size(10)
.Query(q=>q.Match(m=>m.Field(f=>f.LastName).Query("l1"))));
请求 URL 如下:
POST /users/_search?typed_keys=true
- 以上搜索是基于“users”索引来进行搜寻
如何在 ES 上的所有索引上进行搜索?通过 AllIndices(),如下:
var result = _client.Search<User>(s=>s
.AllIndices() //指定在所有索引上进行查询
.From(0)
.Size(10)
.Query(q=>q.Match(m=>m.Field(f=>f.LastName).Query("l1"))));
假设有如下文档:
//users 索引
"hits" : [
{
"_index" : "users",
"_type" : "_doc",
"_id" : "3a351ea1-bfc3-43df-ae12-9c89e22af144",
"_score" : 1.0,
"_source" : {
"id" : "3a351ea1-bfc3-43df-ae12-9c89e22af144",
"firstName" : "f1",
"lastName" : "l1"
}
},
{
"_index" : "users",
"_type" : "_doc",
"_id" : "05245504-053c-431a-984f-23e16d8fbbc9",
"_score" : 1.0,
"_source" : {
"id" : "05245504-053c-431a-984f-23e16d8fbbc9",
"firstName" : "f2",
"lastName" : "l2"
}
}
]
// thirdusers 索引
"hits" : [
{
"_index" : "thirdusers",
"_type" : "_doc",
"_id" : "619ad5f8-c918-46ef-82a8-82a724ca5443",
"_score" : 1.0,
"_source" : {
"firstName" : "f1",
"lastName" : "l1"
}
}
]
则最终可以获取到 users 和 thirdusers 索引中分别获取到 _id 为 3a351ea1-bfc3-43df-ae12-9c89e22af144 和 619ad5f8-c918-46ef-82a8-82a724ca5443 的文档信息。
可以通过 .AllTypes() 和 .AllIndices() 从所有 类型(types) 和 所有 索引(index)中查询数据,最终查询会生成在 /_search 请求中。关于 Type 和 Index,可分别参考:NEST 教程系列 9-6 转换:Document Paths 文档路径和跳转:NEST 教程系列 9-7 转换:Indices Paths 索引路径
通过查询对象进行查询
通过 SearchRequest 对象进行查询。
例:在所有索引查询 LastName="l1"的文档信息
var request = new SearchRequest(Nest.Indices.All) //在所有索引上查询
{
From = 0,
Size = 10,
Query = new MatchQuery
{
Field = Infer.Field<User>(f => f.LastName),
Query = "l1"
}
};
var response = _client.Search<User>(request);
生成的请求 URL 为:
POST /_all/_search?typed_keys=true
通过 .LowLever 属性来使用 Elasticsearch.Net 来进行查询
使用 Elasticsearch.Net 来进行查询的契机:
- 当客户端存在 bug,即使用上述 NEST 的 Search 和 SearchRequest 异常的时候,可以考虑用 Elasticsearch.Net 提供的查询方式。
- 当你希望用一个匿名对象或者 JSON 字符串来进行查询的时候。
var response = _client.LowLevel.Search<SearchResponse<User>>("users", PostData.Serializable(new
{
from = 0,
size = 10,
query = new
{
match = new
{
lastName = "l1"
}
}
}));
聚合查询
除了结构化和非结构化查询之外, ES 同样支持聚合(Aggregations)查询:
var result = _client.Search<User>(s => s
.Size(0) //设置为 0 ,可以让结果只包含聚合的部分:即 hits 属性中没有结果,聚合结果显示在 ”aggregations“
.Query(q =>
q.Match(m =>
m.Field(f => f.FirstName)
.Query("f2")))
.Aggregations(a => //使用 terms 聚合,并指定到桶 last_name 中
a.Terms("last_name", ta =>
ta.Field(f => f.LastName)))
);
- 一般使用 term 聚合来获取每个存储桶的文档数量,其中每个桶将以 lastName 作为关键字。
更多关于聚合的操作可见此:NEST 教程系列 8 聚合:Writing aggregations | 使用聚合
Elastcisearch.Nest 7.x 系列`伪`官方翻译:通过 NEST 来快捷试用 Elasticsearch的更多相关文章
- ST官方翻译的中文应用笔记汇总
ST官方翻译的中文应用笔记汇总 http://www.51hei.com/stm32/3382.html 官方中文AN:AN3116:STM32? 的 ADC 模式及其应用AN1015:用于提高微控制 ...
- 【SFA官方翻译】使用 Kubernetes、Spring Boot 2.0 和 Docker 的微服务快速指南
[SFA官方翻译]使用 Kubernetes.Spring Boot 2.0 和 Docker 的微服务快速指南 原创: Darren Luo SpringForAll社区 今天 原文链接:https ...
- Netty5.x 和3.x、4.x的区别及注意事项(官方翻译)
Netty5.x 和3.x.4.x的区别及注意事项 (官方翻译) 本文档列出了Netty5新版本中值得注意变化和新特性列表.帮助你的应用更好的适应新的版本. 不像Netty3.x和4.x之间的变化 ...
- Qt Model/View(官方翻译,图文并茂)
http://doc.trolltech.com/main-snapshot/model-view-programming.html 介绍 Qt 4推出了一组新的item view类,它们使用mode ...
- Kafka快速上手(2017.9官方翻译)
为了帮助国人更好了解.上手kafka,特意翻译.修改了个文档.官方Wiki : http://kafka.apache.org/quickstart 快速开始 本教程假定您正在开始新鲜,并且没有现有的 ...
- caffe for python (官方翻译)
导言 本教程中,我们将会利用Caffe官方提供的深度模型——CaffeNet(该模型是基于Krizhevsky等人的模型的)来演示图像识别与分类.我们将分别用CPU和GPU来进行演示,并对比其性能.然 ...
- Android性能优化系列 + Android官方培训课程中文版
Android性能优化典范 - 第6季 http://hukai.me/android-performance-patterns-season-6/ Android性能优化典范 - 第5季 htt ...
- Key-Vlaue Coding Apple官方翻译
今天是键值编码,网上有很多文章,可以百度.不太理解的就看官方文档吧 键-值编码 键值编码是一种运用字符串标识符来间接访问一个对象的属性和关系的机制.它尤其强化并关联了多种Cocoa编程的机制和技术,体 ...
- FreeRTOS官方翻译文档——第二章 队列管理
2.1 概览基于 FreeRTOS 的应用程序由一组独立的任务构成——每个任务都是具有独立权限的小程序.这些独立的任务之间很可能会通过相互通信以提供有用的系统功能.FreeRTOS 中所有的通信与同步 ...
随机推荐
- [HNOI2019]白兔之舞
memset0 多合一无聊题 mod k=t,并且k是p-1的约数 单位根反演石锤了. 所以直接设f[i]表示走i步的方案数, 然后C(L,i)分配位置,再A^i进行矩乘得到f[i] 变成生成函数F( ...
- vim 方式快捷编辑代码
说明 **I: ** 行首插入 **a: ** 追加 **A: ** 行尾插入 **R: ** 替换文字 **v: ** 选择 **ctrl-v: ** 选择举行区域 **x: ** 删除 **dd: ...
- JAVA8学习——深入浅出函数式接口FunctionInterface(学习过程)
函数式接口 函数式接口详解:FunctionInterface接口 话不多说,先打开源码,查阅一番.寻得FunctionInterface接口 package java.util.function; ...
- 0029 定位:position(相对、绝对、固定、绝对定位盒子居中、z-index、绝对定位改变display属性)
目标 理解 能说出为什么要用定位 能说出定位的4种分类 能说出四种定位的各自特点 能说出我们为什么常用子绝父相布局 应用 能写出淘宝轮播图布局 1. CSS 布局的三种机制 网页布局的核心 -- 就是 ...
- Linux Centos7 环境基于Docker部署Zookeeper服务搭建实战
配置Zookeeper安装目录 在宿主机配置zookeeper安装目录:/docker/develop/zookeeper 并且在文件夹创建 data 和logs 目录: mkdir -p /dock ...
- 【题解】HDU Homework(倍增)
[题解]HDU Homework(倍增) 矩阵题一定要多多检查一下是否行列反了... 一百个递推项一定要存101个 说多了都是泪啊 一下午就做了这一道题因为实在是太菜了太久没写这种矩阵的题目... 设 ...
- Python+appium+unittest UI自动化测试
什么是UI自动化 自动化分层 单元自动化测试,指对软件中最小可测试单元进行检查和验证,一般需要借助单元测试框架,如java的JUnit,python的unittest等 接口自动化测试,主要检查验证模 ...
- SpringBoot基础架构篇1(SpringBoot、MyBatis-Plus与Thymeleaf)
show me the code and talk to me,做的出来更要说的明白 我是布尔bl,你的支持是我分享的动力! 1 引入 使用 MyBatis-Plus 以及 thymeleaf 实现增 ...
- Python for Data Analysis 学习心得(一) - numpy介绍
一.简介 Python for Data Analysis这本书的特点是将numpy和pandas这两个工具介绍的很详细,这两个工具是使用Python做数据分析非常重要的一环,numpy主要是做矩阵的 ...
- 讲真,这两个IDE插件,可以让你写出质量杠杠的代码
昨晚躺在床上看<拯救大兵瑞恩>的时候,不由得感叹道:"斯皮尔伯格的电影质量真高,片头真实地还原了二战的残酷性."看完后,我的精神异常的亢奋,就想写篇文章来帮助大家提高一 ...