使用put方式,并自己提供id
类似于下面的格式
PUT /{index}/{type}/{id}
{
“field”: “value”,
…
}
请求
PUT /website/blog/123
{
“title”: “My first blog entry”,
“text”: “Just trying this out…”,
“date”: “2014/01/01”
}
响应
{
“_index”: “website”,
“_type”: “blog”,
“_id”: “123”,
“_version”: 1,
“created”: true
}
自动生成的 ID 是 URL-safe、 基于 Base64 编码且长度为20个字符的 GUID 字符串。 这些 GUID 字符串由可修改的 FlakeID 模式生成,这种模式允许多个节点并行生成唯一 ID ,且互相之间的冲突概率几乎为零。
1.2.2.更改操作
Java示例代码:
private static void update() throws IOException {
String type = “_doc”;
String index = “test1”;
// 唯一编号
String id = “1”;
UpdateRequest upateRequest = new UpdateRequest();
upateRequest.id(id);
upateRequest.index(index);
upateRequest.type(type);
// 依旧可以使用Map这种集合作为更新条件
Map<String, Object> jsonMap = new HashMap<>();
jsonMap.put(“uid”, 12345);
jsonMap.put(“phone”, 123456789019L);
jsonMap.put(“msgcode”, 2);
jsonMap.put(“sendtime”, “2019-03-14 01:57:04”);
jsonMap.put(“message”, “xuwujing study Elasticsearch”);
upateRequest.doc(jsonMap);
// upsert 方法表示如果数据不存在,那么就新增一条
upateRequest.docAsUpsert(true);
client.update(upateRequest, RequestOptions.DEFAULT);
System.out.println(“更新成功!”);
}
控制台输入
PUT /website/blog/123
{
“title”: “My first blog entry”,
“text”: “Just trying this out…”,
“date”: “2014/01/01”
}
在响应体中,我们能看到 Elasticsearch 已经增加了 _version 字段值,created 标志设置成 false ,是因为相同的索引、类型和 ID 的文档已经存在。
{
“_index”: “website”,
“_type”: “blog”,
“_id”: “123”,
“_version”: 2,
“created”: false
}
1.2.3.删除操作
Java示例代码:
示例一(正常根据ID删除):
private static void delete() throws IOException {
String type = “_doc”;
String index = “test1”;
// 唯一编号
String id = “1”;
DeleteRequest deleteRequest = new DeleteRequest();
deleteRequest.id(id);
deleteRequest.index(index);
deleteRequest.type(type);
// 设置超时时间
deleteRequest.timeout(TimeValue.timeValueMinutes(2));
// 设置刷新策略"wait_for"
// 保持此请求打开,直到刷新使此请求的内容可以搜索为止。此刷新策略与高索引和搜索吞吐量兼容,但它会导致请求等待响应,直到发生刷新
deleteRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL);
// 同步删除
DeleteResponse deleteResponse = client.delete(deleteRequest, RequestOptions.DEFAULT);
}
示例二(条件删除):
private static void deleteByQuery() throws IOException {
String type = “_doc”;
String index = “test1”;
DeleteByQueryRequest request = new DeleteByQueryRequest(index,type);
// 设置查询条件
request.setQuery(QueryBuilders.termsQuery(“uid”,1234));
// 同步执行
BulkByScrollResponse bulkResponse = client.deleteByQuery(request, RequestOptions.DEFAULT);
}
DELETE /website/blog/123
如果找到该文档,Elasticsearch 将要返回一个 200 ok 的 HTTP 响应码,和一个类似以下结构的响应体。注意,字段 _version 值已经增加:
{
“found” : true,
“_index” : “website”,
“_type” : “blog”,
“_id” : “123”,
“_version” : 3
}
如果文档没有 找到,我们将得到 404 Not Found 的响应码和类似这样的响应体:
{
“found” : false,
“_index” : “website”,
“_type” : “blog”,
“_id” : “123”,
“_version” : 4
}
1.2.4.查询操作
查询API
等值(term查询:QueryBuilders.termQuery(name,value);
多值(terms)查询:QueryBuilders.termsQuery(name,value,value2,value3…);
范围(range)查询:QueryBuilders.rangeQuery(name).gte(value).lte(value);
存在(exists)查询:QueryBuilders.existsQuery(name);
模糊(wildcard)查询:QueryBuilders.wildcardQuery(name,+value+);
组合(bool)查询: BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
1.2.4.1.查询所有代码示例
在这里插入代码片 private static void allSearch() throws IOException {
SearchRequest searchRequestAll = new SearchRequest();
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
searchRequestAll.source(searchSourceBuilder);
// 同步查询
SearchResponse searchResponseAll = client.search(searchRequestAll, RequestOptions.DEFAULT);
System.out.println(“所有查询总数:” + searchResponseAll.getHits().getTotalHits());
}
1.2.4.2.一般查询代码示例
private static void genSearch() throws IOException {
String type = “_doc”;
String index = “test1”;
// 查询指定的索引库
SearchRequest searchRequest = new SearchRequest(index);
searchRequest.types(type);
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 设置查询条件
sourceBuilder.query(QueryBuilders.termQuery(“uid”, “1234”));
// 设置起止和结束
sourceBuilder.from(0);
sourceBuilder.size(5);
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
// 设置路由
// searchRequest.routing(“routing”);
// 设置索引库表达式
searchRequest.indicesOptions(IndicesOptions.lenientExpandOpen());
// 查询选择本地分片,默认是集群分片
searchRequest.preference(“_local”);
// 排序
// 根据默认值进行降序排序
// sourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC));
// 根据字段进行升序排序
// sourceBuilder.sort(new FieldSortBuilder(“id”).order(SortOrder.ASC));
// 关闭suorce查询
// sourceBuilder.fetchSource(false);
String[] includeFields = new String[]{“title”, “user”, “innerObject.*”};
String[] excludeFields = new String[]{“_type”};
// 包含或排除字段
// sourceBuilder.fetchSource(includeFields, excludeFields);
searchRequest.source(sourceBuilder);
System.out.println(“普通查询的DSL语句:”+sourceBuilder.toString());
// 同步查询
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
// HTTP状态代码、执行时间或请求是否提前终止或超时
RestStatus status = searchResponse.status();
TimeValue took = searchResponse.getTook();
Boolean terminatedEarly = searchResponse.isTerminatedEarly();
boolean timedOut = searchResponse.isTimedOut();
// 供关于受搜索影响的切分总数的统计信息,以及成功和失败的切分
int totalShards = searchResponse.getTotalShards();
int successfulShards = searchResponse.getSuccessfulShards();
int failedShards = searchResponse.getFailedShards();
// 失败的原因
for (ShardSearchFailure failure : searchResponse.getShardFailures()) {
// failures should be handled here
}
// 结果
searchResponse.getHits().forEach(hit -> {
Map<String, Object> map = hit.getSourceAsMap();
System.out.println(“普通查询的结果:” + map);
});
System.out.println(“\n=================\n”);
}
1.2.4.3.或查询代码示例
private static void orSearch() throws IOException {
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices(“test1”);
searchRequest.types(“_doc”);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
BoolQueryBuilder boolQueryBuilder2 = new BoolQueryBuilder();
/**
-
SELECT * FROM test1 where (uid = 1234 or uid =12345) and phone = 12345678909
-
*/
boolQueryBuilder2.should(QueryBuilders.termQuery(“uid”, 1234));
boolQueryBuilder2.should(QueryBuilders.termQuery(“uid”, 12345));
boolQueryBuilder.must(boolQueryBuilder2);
boolQueryBuilder.must(QueryBuilders.termQuery(“phone”, “12345678909”));
searchSourceBuilder.query(boolQueryBuilder);
System.out.println(“或查询语句:” + searchSourceBuilder.toString());
searchRequest.source(searchSourceBuilder);
// 同步查询
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
searchResponse.getHits().forEach(documentFields -> {
System.out.println(“查询结果:” + documentFields.getSourceAsMap());
});
}
1.2.4.4.模糊查询代码示例
模糊查询
相当于SQL语句中的like查询。
private static void likeSearch() throws IOException {
String type = “_doc”;
String index = “test1”;
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices(index);
searchRequest.types(type);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
/**
-
SELECT * FROM p_test where message like ‘%xu%’;
-
*/
boolQueryBuilder.must(QueryBuilders.wildcardQuery(“message”, “xu”));
searchSourceBuilder.query(boolQueryBuilder);
System.out.println(“模糊查询语句:” + searchSourceBuilder.toString());
searchRequest.source(searchSourceBuilder);
// 同步查询
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
searchResponse.getHits().forEach(documentFields -> {
System.out.println(“模糊查询结果:” + documentFields.getSourceAsMap());
});
System.out.println(“\n=================\n”);
}
1.2.4.5.多值查询代码示例
也就是相当于SQL语句中的in查询。
private static void inSearch() throws IOException {
String type = “_doc”;
String index = “test1”;
// 查询指定的索引库
SearchRequest searchRequest = new SearchRequest(index,type);
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
/**
-
SELECT * FROM p_test where uid in (1,2)
-
*/
// 设置查询条件
sourceBuilder.query(QueryBuilders.termsQuery(“uid”, 1, 2));
searchRequest.source(sourceBuilder);
System.out.println(“in查询的DSL语句:”+sourceBuilder.toString());
// 同步查询
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
// 结果
searchResponse.getHits().forEach(hit -> {
Map<String, Object> map = hit.getSourceAsMap();
String string = hit.getSourceAsString();
System.out.println(“in查询的Map结果:” + map);
System.out.println(“in查询的String结果:” + string);
});
System.out.println(“\n=================\n”);
}
1.2.4.6.存在查询
判断是否存在该字段,用法和SQL语句中的exist类似。
private static void existSearch() throws IOException {
String type = “_doc”;
String index = “test1”;
// 查询指定的索引库
SearchRequest searchRequest = new SearchRequest(index);
searchRequest.types(type);
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 设置查询条件
sourceBuilder.query(QueryBuilders.existsQuery(“msgcode”));
searchRequest.source(sourceBuilder);
System.out.println(“存在查询的DSL语句:”+sourceBuilder.toString());
// 同步查询
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
// 结果
searchResponse.getHits().forEach(hit -> {
Map<String, Object> map = hit.getSourceAsMap();
String string = hit.getSourceAsString();
System.out.println(“存在查询的Map结果:” + map);
System.out.println(“存在查询的String结果:” + string);
});
System.out.println(“\n=================\n”);
}
1.2.4.7.范围查询
和SQL语句中<>使用方法一样,其中gt是大于,lt是小于,gte是大于等于,lte是小于等于。
private static void rangeSearch() throws IOException{
String type = “_doc”;
String index = “test1”;
SearchRequest searchRequest = new SearchRequest(index);
searchRequest.types(type);
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 设置查询条件
sourceBuilder.query(QueryBuilders.rangeQuery(“sendtime”).gte(“2019-01-01 00:00:00”).lte(“2019-12-31 23:59:59”));
searchRequest.source(sourceBuilder);
System.out.println(“范围查询的DSL语句:”+sourceBuilder.toString());
// 同步查询
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
// 结果
searchResponse.getHits().forEach(hit -> {
String string = hit.getSourceAsString();
System.out.println(“范围查询的String结果:” + string);
});
System.out.println(“\n=================\n”);
}
1.2.4.8.正则查询
ES可以使用正则进行查询,查询方式也非常的简单,代码示例如下:
private static void regexpSearch() throws IOException{
String type = “_doc”;
String index = “test1”;
// 查询指定的索引库
SearchRequest searchRequest = new SearchRequest(index);
searchRequest.types(type);
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 设置查询条件
sourceBuilder.query(QueryBuilders.regexpQuery(“message”,“xu[0-9]”));
searchRequest.source(sourceBuilder);
System.out.println(“正则查询的DSL语句:”+sourceBuilder.toString());
// 同步查询
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
// 结果
searchResponse.getHits().forEach(hit -> {
Map<String, Object> map = hit.getSourceAsMap();
String string = hit.getSourceAsString();
System.out.println(“正则查询的Map结果:” + map);
System.out.println(“正则查询的String结果:” + string);
});
System.out.println(“\n=================\n”);
}
2.1Elasticsearch是如何实现Master选举的?
Elasticsearch的选主是ZenDiscovery模块负责的,主要包含Ping(节点之间通过这个RPC来发现彼此)和Unicast(单播模块包含一个主机列表以控制哪些节点需要ping通)这两部分;
对所有可以成为master的节点(node.master: true)根据nodeId字典排序,每次选举每个节点都把自己所知道节点排一次序,然后选出第一个(第0位)节点,暂且认为它是master节点。
如果对某个节点的投票数达到一定的值(可以成为master节点数n/2+1)并且该节点自己也选举自己,那这个节点就是master。否则重新选举一直到满足上述条件。
补充:master节点的职责主要包括集群、节点和索引的管理,不负责文档级别的管理;data节点可以关闭http功能。
2.2 Elasticsearch中的节点(比如共20个),其中的10个选了一个master,另外10个选了另一个master,怎么办?
当集群master候选数量不小于3个时,可以通过设置最少投票通过数量(discovery.zen.minimum_master_nodes)超过所有候选节点一半以上来解决脑裂问题;
当候选数量为两个时,只能修改为唯一的一个master候选,其他作为data节点,避免脑裂问题。
2.3 客户端在和集群连接时,如何选择特定的节点执行请求的?
TransportClient利用transport模块远程连接一个elasticsearch集群。它并不加入到集群中,只是简单的获得一个或者多个初始化的transport地址,并以 轮询 的方式与这些地址进行通信。
2.4 详细描述一下Elasticsearch索引文档的过程。
协调节点默认使用文档ID参与计算(也支持通过routing),以便为路由提供合适的分片。
shard = hash(document_id) % (num_of_primary_shards)
当分片所在的节点接收到来自协调节点的请求后,会将请求写入到Memory Buffer,然后定时(默认是每隔1秒)写入到Filesystem Cache,这个从Momery Buffer到Filesystem Cache的过程就叫做refresh;
当然在某些情况下,存在Momery Buffer和Filesystem Cache的数据可能会丢失,ES是通过translog的机制来保证数据的可靠性的。其实现机制是接收到请求后,同时也会写入到translog中,当Filesystem cache中的数据写入到磁盘中时,才会清除掉,这个过程叫做flush;
在flush过程中,内存中的缓冲将被清除,内容被写入一个新段,段的fsync将创建一个新的提交点,并将内容刷新到磁盘,旧的translog将被删除并开始一个新的translog。
flush触发的时机是定时触发(默认30分钟)或者translog变得太大(默认为512M)时;
2.5 详细描述一下Elasticsearch更新和删除文档的过程。
删除和更新也都是写操作,但是Elasticsearch中的文档是不可变的,因此不能被删除或者改动以展示其变更;
磁盘上的每个段都有一个相应的.del文件。当删除请求发送后,文档并没有真的被删除,而是在.del文件中被标记为删除。该文档依然能匹配查询,但是会在结果中被过滤掉。当段合并时,在.del文件中被标记为删除的文档将不会被写入新段。
在新的文档被创建时,Elasticsearch会为该文档指定一个版本号,当执行更新时,旧版本的文档在.del文件中被标记为删除,新版本的文档被索引到一个新段。旧版本的文档依然能匹配查询,但是会在结果中被过滤掉。
2.6 详细描述一下Elasticsearch搜索的过程。
搜索被执行成一个两阶段过程,我们称之为 Query Then Fetch;
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
asticsearch中的文档是不可变的,因此不能被删除或者改动以展示其变更;
磁盘上的每个段都有一个相应的.del文件。当删除请求发送后,文档并没有真的被删除,而是在.del文件中被标记为删除。该文档依然能匹配查询,但是会在结果中被过滤掉。当段合并时,在.del文件中被标记为删除的文档将不会被写入新段。
在新的文档被创建时,Elasticsearch会为该文档指定一个版本号,当执行更新时,旧版本的文档在.del文件中被标记为删除,新版本的文档被索引到一个新段。旧版本的文档依然能匹配查询,但是会在结果中被过滤掉。
2.6 详细描述一下Elasticsearch搜索的过程。
搜索被执行成一个两阶段过程,我们称之为 Query Then Fetch;
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-BszOxCE6-1715434079213)]
[外链图片转存中…(img-jIbFH718-1715434079214)]
[外链图片转存中…(img-di6WmC7X-1715434079214)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!