关于 ElasticSearch的学习参见:ELK | wjcx_sqh

本文分别学习 .Net | Java 下操作 ES:

.Net

目前主流的 .Net 客户端有 2 种:

  • PlainElastic.Net
  • Elasticsearch.Net.dll 和 Nest.dll

PlainElastic.Net 简单了解即可,具体参见:https://www.cnblogs.com/eggTwo/p/4039779.html

Elasticsearch.Net + Nest

直接在Nuget | 官网下载对应的.nuget包,项目中引入即可。注意不同版本.dll对.Net框架的依赖

索引

创建连接(连接池

var nodes = new Uri[] { new Uri("http://ip1:9200"), new Uri("http://ip2:9200") };
var pool = new StaticConnectionPool(nodes); //推荐使用
var settings = new ConnectionSettings(pool);
var ESClient = new ElasticClient(settings);

其他配置参见:

settings.DefaultIndex("defaultidx"); //指定默认索引
settings.DefaultFieldNameInferrer((name) => name) //与Model字段同名,避免出现字段不一致的情况
settings.BasicAuthentication("username", "password"); //用户认证
settings.RequestTimeout(new TimeSpan(10000)); //请求超时设置
settings.MaximumRetries(2); //最大重试次数
settings.MaxRetryTimeout(new TimeSpan(50000)); //重试超时时间, 默认是RequestTimeout
settings.DisableDirectStreaming(true); //开启debug调试,生产环境建议关闭

配置回调方法

settings.OnRequestCompleted(apiCallDetails => { //请求完成 返回 apiCallDetails });
settings.OnRequestDataCreated(requestData => { //请求的数据创建完成 返回请求的数据 });

索引判断和创建

var descriptor = new CreateIndexDescriptor("idxName").Settings(s => s.NumberOfShards(5).NumberOfReplicas(1));
client.CreateIndex(descriptor); if (!client.TypeExists(_indexName, _typeName).Exists) {
client.CreateIndex(_indexName, p => p.InitializeUsing(_indexState)
.Mappings(m => m.Map<DefClassName>(mp => mp.AutoMap()))); }
protected static IIndexState _indexState = new IndexState() { //索引配置
Settings = new IndexSettings() {
NumberOfReplicas = 1, NumberOfShards = 5
}}; client.IndexExists("index_name"); //判断
client.DeleteIndex("index_name"); //删除

一旦mapping原字段不能再修改,需删除再重新创建。其中DefClassName:

[ElasticsearchType(Name = "TYPE_NAME")]
public class AFVInfo {
[Keyword(Name = "field1", Index = true, IgnoreAbove = 20)]
public string field1 { get; set; } [Text(Name = "field2",Index= false)]
public string field2 { get; set; } public DateTime dt{ get; set; }
}

通过配置各字段的KeywordText属性即可完成创建索引时的映射。Elasticsearch.net client NEST

但是,可以新增其他字段

var result = _client.Map<AFVInfo>(m => m.Index(indexName).Properties(p => p
.Keyword(s => s.Name("field_name1").Index(true))
.Text(s=>s.Name("field_name2").Index(false))
));

调试:获取ES交互时的请求和响应

var requestStr = System.Text.Encoding.UTF8.GetString(result.ApiCall.RequestBodyInBytes);
var responseStr = System.Text.Encoding.UTF8.GetString(result.ApiCall.ResponseBodyInBytes);

查询

对象方式查询Fluent API

TermQuery 是整词搜索;MatchQuery 是按分词器分词搜索,可以搭配from和size从指定位置返回指定条数。

注意 match 与 match_phrase 的不同。

Search After

通过上一页的结果检索下一页,使用search_after参数时,from的值必须设为0或-1:search_after

  • from和size:深度分页或size特别大时,会出deep pagination,es自保机制max_result_window预设值10000,建议from + size <= 1万
  • scroll:代表某时刻的snapshot,不适合实时查询,scroll后接超时时间,频繁发起scroll请求,也会出现一系列问题

search_after解决scroll的非实时取值问题,提供live cursor规避消耗存储和时间的性能问题:search_after性能

Source Filter

推荐在查询请求SearchRequest中使用,按需返回字段

sr.Source = new SourceFilter() {
Includes = new string[] { "xx", "zz" }, Excludes = new string[] { "vv" }
};

问题解决

问题1:Kibana显示的时间比实际插入ES的时间多8个小时

原因:NEST的序列化器默认DateTime类型是UTC时区,序列化时丢弃了时区信息,而Kibana设置是东八区

解决:创建client时传入设置参数

var settings = new ConnectionSettings(pool,
sourceSerializer: (builtin, setting) => new JsonNetSerializer(builtin, setting,
() => new Newtonsoft.Json.JsonSerializerSettings {
DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Local
}));

问题2:实现超时自动重试

解决:通过添加max_retries和retry_on_timeout两个参数

es = Elasticsearch( hosts=[{'host': 'localhost', 'port': 9200}], timeout=60, max_retries=3, retry_on_timeout=True);

序列化

ElasticSearch 是 Restful 相关,自然经常用到 json

推荐学习:Custom Serialization

说到json,自然需要解析,提供2种方式:JsonPathLinq to JSON

log4net.ElasticSearch

除了调用ES对外的接口,还可以直接向ES写日志:log4net.ElasticSearch

<appender name="ElasticSearchAppender" type="log4net.ElasticSearch.ElasticSearchAppender, log4net.ElasticSearch">
<layout type="log4net.Layout.PatternLayout,log4net">
<param name="ConversionPattern" value="%d{ABSOLUTE} %-5p %c{1}:%L - %m%n" />
</layout>
<connectionString value="Server=xxx.xxx.xxx.xxx;Index=logsqh;Port=9200;rolling=false"/>
<lossy value="false" />
<evaluator type="log4net.Core.LevelEvaluator">
<threshold value="ALL" />
</evaluator>
<bufferSize value="1" />
</appender>

其中,rolling属性控制是否每天生成一个索引,具体参见:log4net.ElasticSearch+ Kibana日志记录和显示

Java

原生API

  • transport:TCP,只支持java
  • rest:http,无语言限制

建议rest,transport将在v7.0、v8.0中逐步废弃。

SpringBoot + Elasticsearch

SpringBoot集成Elasticsearch,支持4种方式

  • REST Client:http,Java Low Level Rest Client和推荐:Java High Level Rest Client
  • Jest:http,java社区版
  • Spring Data:spring集成elasticsearch开发包
  • Spring Data Repositories

Spring Data Elasticsearch

Spring Data 子模块套件,支持快速初始化maven项,官网移步参考示例

  • SpringBoot:v2.2.2
  • Elasticsearch:v6.8.0

务必保证SpringBoot和Elasticsearch的版本匹配,对应关系

High Level Rest Client

版本配置:sb-2.2.2 + es-6.6.2

<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>6.6.2</version>

初始引用v6.1.4会报错:org.elasticsearch.client.Request.<init>(Ljava/lang/String;Ljava/lang/String;)V

提供一个ES的客户端配置示例

private String schema = "http";
private int connectTimeOut = 1000;
private int socketTimeOut = 30000;
private int connectionRequestTimeOut = 500;
private int maxConnectNum = 100;
private int maxConnectPerRoute = 100;
private boolean uniqueConnectTimeConfig = true;
private boolean uniqueConnectNumConfig = true;
private RestClientBuilder builder;
private RestHighLevelClient client; List<HttpHost> httpHosts = new ArrayList<>();
HttpHost it = new HttpHost(host, port, schema);
httpHosts.add(it); @Bean(autowire = Autowire.BY_NAME, name = "restHighLevelClient")
public RestHighLevelClient client() {
try {
builder = RestClient.builder(httpHosts.toArray(new HttpHost[0]));
if (uniqueConnectTimeConfig) { setConnectTimeOutConfig(); }
if (uniqueConnectNumConfig) { setMutiConnectConfig(); }
client = new RestHighLevelClient(builder);
return client;
} catch (NumberFormatException e) { }
return null;
} /**
* 异步httpclient的连接延时配置
*/
public void setConnectTimeOutConfig() {
builder.setRequestConfigCallback(new RestClientBuilder.RequestConfigCallback() {
@Override
public Builder customizeRequestConfig(Builder requestConfigBuilder) {
requestConfigBuilder.setConnectTimeout(connectTimeOut);
requestConfigBuilder.setSocketTimeout(socketTimeOut);
requestConfigBuilder.setConnectionRequestTimeout(connectionRequestTimeOut);
return requestConfigBuilder;
}
});
}
/**
* 异步httpclient的连接数配置
*/
public void setMutiConnectConfig() {
builder.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
@Override
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
httpClientBuilder.setMaxConnTotal(maxConnectNum);
httpClientBuilder.setMaxConnPerRoute(maxConnectPerRoute);
return httpClientBuilder;
}
});
}

若是需认证,客户端注入参考如下方法

@Bean(autowire = Autowire.BY_NAME, name = "restHighLevelClientNew")
public RestHighLevelClient newClient() {
try {
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(newESUserName,newESUserPassWord));
builder = RestClient.builder(httpHosts.toArray(new HttpHost[0]))
.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
@Override
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpAsyncClientBuilder) {
return httpAsyncClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
}
});
String auth = Base64Util.decode((_esUserName + ":" + _esUserPassWord).getBytes());
builder.setDefaultHeaders(new BasicHeader[]{new BasicHeader("Authorization", "Basic " + auth)}); if (uniqueConnectTimeConfig) { setNewConnectTimeOutConfig(); }
if (uniqueConnectNumConfig) { setNewMutiConnectConfig(); }
newClient = new RestHighLevelClient(newBuilder);
return newClient;
} catch (NumberFormatException e) { }
return null;
}

参考学习:示例1示例2

BulkMulti-GetReindexUpdate by queryDelete by queryRethrottle

多记录操作-RestClient

ES Client的更多相关文章

  1. elasticsearch系列七:ES Java客户端-Elasticsearch Java client(ES Client 简介、Java REST Client、Java Client、Spring Data Elasticsearch)

    一.ES Client 简介 1. ES是一个服务,采用C/S结构 2. 回顾 ES的架构 3. ES支持的客户端连接方式 3.1 REST API ,端口 9200 这种连接方式对应于架构图中的RE ...

  2. Elasticsearch Java client(ES Client 简介、Java REST Client、Java Client、Spring Data Elasticsearch)

    elasticsearch系列七:ES Java客户端-Elasticsearch Java client(ES Client 简介.Java REST Client.Java Client.Spri ...

  3. go-elasticsearch 来自官方的 golang es client

    elasticsearch 终于有了官方的golang sdk 了,地址 https://github.com/elastic/go-elasticsearch 当前还不稳定,同时主要是对于es7 的 ...

  4. Elasticsearch之client源码简要分析

    问题 让我们带着问题去学习,效率会更高 1  es集群只配置一个节点,client是否能够自动发现集群中的所有节点?是如何发现的? 2  es client如何做到负载均衡? 3  一个es node ...

  5. Spark2.2+ES6.4.2(三十二):ES API之index的create/update/delete/open/close(创建index时设置setting,并创建index后根据avro模板动态设置index的mapping)

    要想通过ES API对es的操作,必须获取到TransportClient对象,让后根据TransportClient获取到IndicesAdminClient对象后,方可以根据IndicesAdmi ...

  6. Kafka:ZK+Kafka+Spark Streaming集群环境搭建(二十)ES6.2.2 Client API

    scala版本2.11 java版本1.8 spark版本2.2.1 es版本6.2.2 hadoop版本2.9.0 elasticsearch节点列表: 192.168.0.120 192.168. ...

  7. ES异常处理-NoNodeAvailableException

    1.问题描述 ES client客户端能创建,但是在用客户端操作时报:NoNodeAvailableException[None of the configured nodes are availab ...

  8. 「Elasticsearch」SpringBoot快速集成ES

    Elastic Search 的底层是开源库 Lucene.但是Lucene的使用门槛比较高,必须自己写代码去调用它的接口.而Elastic Search的出现正是为了解决了这个问题,它是 Lucen ...

  9. 1W字|40 图|硬核 ES 实战

    前言 上篇我们讲到了 Elasticsearch 全文检索的原理<别只会搜日志了,求你懂点检索原理吧>,通过在本地搭建一套 ES 服务,以多个案例来分析了 ES 的原理以及基础使用.这次我 ...

随机推荐

  1. bladex之nacos配置

    blade.yaml #服务器配置server:  undertow:    # 设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个CPU核心一个线程    io-threa ...

  2. 【源码解析】Flink 是如何基于事件时间生成Timestamp和Watermark

    生成Timestamp和Watermark 的三个重载方法介绍可参见上一篇博客: Flink assignAscendingTimestamps 生成水印的三个重载方法 之前想研究下Flink是怎么处 ...

  3. LeetCode_206. Reverse Linked List

    206. Reverse Linked List Easy Reverse a singly linked list. Example: Input: 1->2->3->4-> ...

  4. Nginx配置自定义的403页面

    1.开启nginx的状态码,虚拟主机配置中加入下边一段 location /nginx_status{ stub_status on; access_log off; } 或着在nginx的http模 ...

  5. swift 日历的制作

    制作日历步骤 1.日期数据的处理,这个可以 添加 extension 解决 extension NSDate{ /*几年几月 这个月的多少天*/ class func getDaysInMonth( ...

  6. js禁止退出当前页面

    禁止用户退出网页,就一个添加窗体历史状态方法,代码很简单,但是建议大家不要去使用,会给用户带来不友好的体验,我这里只是学习这种方法,看到自己代码上有也知道在哪里改变这些代码,所以分享一下: 实现原理: ...

  7. Django之用户注册

    用户注册需要提交的信息包括: 用户名 邮箱 密码 确认密码 验证码 这里选择form表单提交信息,注册页面的响应函数就要分条件执行,get请求时要展示注册页面,post请求时要接收用户提交的信息,对信 ...

  8. php设计模式;抽象类、抽象方法

    设计模式 什么叫设计模式 所谓设计模式,就是一些解决问题的“常规做法”,是一种认为较好的经验总结.面对不同的问题,可能会有不同的解决办法,此时就可以称为不同的设计模式. 工厂模式 在实际应用中,我们总 ...

  9. pytorch1.0神经网络保存、提取、加载

    pytorch1.0网络保存.提取.加载 import torch import torch.nn.functional as F # 包含激励函数 import matplotlib.pyplot ...

  10. 030 Android 第三方开源下拉框:NiceSpinner的使用+自定义Button样式+shape绘制控件背景图+图片选择器(selector)

    1.NiceSpinner下拉框控件介绍 Android原生的下拉框Spinner基本上可以满足Android开发对于下拉选项的设计需求,但现在越来越流行的下拉框不满足于Android原生提供的下拉框 ...