简单研究下Java High Level REST Client 的使用方法。这个Client连接的端口是ES的HTTP端口。
0.pom
org.elasticsearch.client
elasticsearch-rest-high-level-client
7.8.1
启动两个ES服务:
elasticsearch.bat -Ehttp.port=9200 -Epath.data=E:/data/0elasticsearch.bat-Ehttp.port=19200 -Epath.data=E:/data/1
1.Index相关API
0.获取所有的Index
private static void getAllIndex() throws IOException { //on startup
RestHighLevelClient client = newRestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 19200, "http")));try{
GetAliasesRequest request= newGetAliasesRequest();
GetAliasesResponse getAliasesResponse=client.indices().getAlias(request, RequestOptions.DEFAULT);
Map> aliases =getAliasesResponse.getAliases();
Set indices =aliases.keySet();for(String key : indices) {
System.out.println(key);
}
}catch(IOException e) {
e.printStackTrace();
}//on shutdown
client.close();
}
结果:
test
.kibana_task_manager_1
.apm-agent-configuration
accounts
.kibana_1
users
1.创建Index
private static void creareIndex() throwsIOException {//on startup
RestHighLevelClient client = newRestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 19200, "http")));
CreateIndexRequest request= new CreateIndexRequest("test");//设置分片数量和副本数量
request.settings(Settings.builder().put("index.number_of_shards", 3).put("index.number_of_replicas", 2));//字段映射
Map message = new HashMap<>();
message.put("type", "text");
Map properties = new HashMap<>();
properties.put("message", message);
Map mapping = new HashMap<>();
mapping.put("properties", properties);
request.mapping(mapping);//执行创建请求
CreateIndexResponse createIndexResponse =client.indices().create(request, RequestOptions.DEFAULT);boolean acknowledged =createIndexResponse.isAcknowledged();boolean shardsAcknowledged =createIndexResponse.isShardsAcknowledged();
System.out.println(acknowledged&&shardsAcknowledged);//on shutdown
client.close();
}
2. 判断是否存在
private static void exists() throwsIOException {//on startup
RestHighLevelClient client = newRestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 19200, "http")));
GetIndexRequest request= new GetIndexRequest("test");boolean exists =client.indices().exists(request, RequestOptions.DEFAULT);
System.out.println(exists);//on shutdown
client.close();
}
3.获取Index的分片数量和副本数量
private static void GetIndexRequest() throwsIOException {//on startup
RestHighLevelClient client = newRestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 19200, "http")));
GetSettingsRequest request= new GetSettingsRequest().indices("test");
GetSettingsResponse getSettingsResponse=client.indices().getSettings(request, RequestOptions.DEFAULT);
String numberOfShardsString= getSettingsResponse.getSetting("test", "index.number_of_shards");
System.out.println(numberOfShardsString);
Settings indexSettings= getSettingsResponse.getIndexToSettings().get("test");
Integer numberOfShards= indexSettings.getAsInt("index.number_of_shards", null);
System.out.println(numberOfShards);//on shutdown
client.close();
}
4.获取Mapping
private static void getMapping() throwsIOException {//on startup
RestHighLevelClient client = newRestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 19200, "http")));
GetMappingsRequest request= newGetMappingsRequest();
request.indices("test");
GetMappingsResponse getMappingResponse=client.indices().getMapping(request, RequestOptions.DEFAULT);
Map allMappings =getMappingResponse.mappings();
MappingMetadata indexMapping= allMappings.get("test");
Map mapping =indexMapping.sourceAsMap();
System.out.println(mapping);//on shutdown
client.close();
}
结果:
{properties={message={type=text}}}
5.修改Mapping
private static void putMapping() throwsIOException {//on startup
RestHighLevelClient client = newRestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 19200, "http")));
PutMappingRequest request= new PutMappingRequest("test");
Map jsonMap = new HashMap<>();
Map message = new HashMap<>();
message.put("type", "text");
Map properties = new HashMap<>();
properties.put("message", message);
jsonMap.put("properties", properties);
request.source(jsonMap);
AcknowledgedResponse putMappingResponse=client.indices().putMapping(request, RequestOptions.DEFAULT);boolean acknowledged =putMappingResponse.isAcknowledged();
System.out.println(acknowledged);//on shutdown
client.close();
}
6.删除Index
private static void delete() throws IOException { //on startup
RestHighLevelClient client = newRestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 19200, "http")));try{//索引不存在抛出ElasticsearchException异常
DeleteIndexRequest request = new DeleteIndexRequest("does_not_exist");
AcknowledgedResponse delete=client.indices().delete(request, RequestOptions.DEFAULT);boolean acknowledged =delete.isAcknowledged();
System.out.println(acknowledged);
}catch(ElasticsearchException exception) {if (exception.status() ==RestStatus.NOT_FOUND) {
}
}//on shutdown
client.close();
}
补充: 上面的操作都有异步操作,例如
private static void delete() throwsIOException, InterruptedException {
CountDownLatch countDownLatch= new CountDownLatch(1);//on startup
RestHighLevelClient client = newRestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 19200, "http")));try{//索引不存在抛出ElasticsearchException异常
DeleteIndexRequest request = new DeleteIndexRequest("test");
ActionListener listener = new ActionListener() {
@Overridepublic voidonResponse(AcknowledgedResponse deleteIndexResponse) {
System.out.println("1");
System.out.println(deleteIndexResponse.isAcknowledged());
countDownLatch.countDown();
}
@Overridepublic voidonFailure(Exception e) {
System.out.println("2");
e.printStackTrace();
countDownLatch.countDown();
}
};
client.indices().deleteAsync(request, RequestOptions.DEFAULT, listener);
}catch(ElasticsearchException exception) {if (exception.status() ==RestStatus.NOT_FOUND) {
System.out.println("3");
exception.printStackTrace();
countDownLatch.countDown();
}
}
countDownLatch.await();//on shutdown
client.close();
}
上面是异步操作的方法,增加listener监听器。加CountDownLatch进行await是为了进行测试效果。实际中不应该使用闭锁。
2.Document APIs
0.准备Index-news 使用IK分词器(关于ES整合IK分词器参考之前的)
private static void createIndex() throwsIOException {//on startup
RestHighLevelClient client = newRestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 19200, "http")));
CreateIndexRequest request= new CreateIndexRequest("news");//设置分片数量和副本数量
request.settings(Settings.builder().put("index.number_of_shards", 3).put("index.number_of_replicas", 2));//字段映射
Map properties = new HashMap<>();
properties.put("id", getField("long"));
properties.put("type", getField("keyword"));
properties.put("title", getField("text"));
properties.put("content", getField("text"));
properties.put("creator", getField("keyword"));
properties.put("createTime", getField("date"));
Map mapping = new HashMap<>();
mapping.put("properties", properties);
request.mapping(mapping);//执行创建请求
CreateIndexResponse createIndexResponse =client.indices().create(request, RequestOptions.DEFAULT);boolean acknowledged =createIndexResponse.isAcknowledged();boolean shardsAcknowledged =createIndexResponse.isShardsAcknowledged();
System.out.println(acknowledged&&shardsAcknowledged);//on shutdown
client.close();
}private static MapgetField(String type) {
Map result = new HashMap<>();
result.put("type", type);if ("text".equals(type)) {
result.put("analyzer", "ik_max_word");
result.put("search_analyzer", "ik_smart");
}returnresult;
}
查看字段映射如下:
{properties={creator={type=keyword}, createTime={type=date}, id={type=long}, title={search_analyzer=ik_smart, analyzer=ik_max_word, type=text}, type={type=keyword}, content={search_analyzer=ik_smart, analyzer=ik_max_word, type=text}}}
1.创建索引
private static void createDoc() throwsIOException {//on startup
RestHighLevelClient client = newRestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 19200, "http")));
String[] type= { "杂文", "java", "vue", "js", "es"};
String[] title= { "杂文记录", "java记录", "vue记录", "js记录", "js记录"};
String[] content= { "这里是杂文记录", "这里是java记录", "这里是vue记录", "这里是js记录", "这里是js记录"};
Map jsonMap = new HashMap<>();for (int i = 0; i < 9; i++) {
jsonMap.clear();int indexNum = i % 5;
jsonMap.put("type", type[indexNum]);
jsonMap.put("title", title[indexNum]);
jsonMap.put("content", content[indexNum]);
jsonMap.put("creator", "creator" +i);
jsonMap.put("createTime", newDate());
IndexRequest indexRequest= new IndexRequest("news").source(jsonMap);
IndexResponse response=client.index(indexRequest, RequestOptions.DEFAULT);
System.out.println("=============" +i);//打印保存信息//Index name
String _index =response.getIndex();
System.out.println("_index " +_index);//Type name
String _type =response.getType();
System.out.println("_type " +_type);//Document ID (generated or not)
String _id =response.getId();
System.out.println("_id " +_id);//Version (if it's the first time you index this document, you will//get: 1)
long _version =response.getVersion();
System.out.println("_version " +_version);//status has stored current instance statement.
RestStatus status =response.status();
System.out.println("status " +status);
}//on shutdown
client.close();
}
结果:
=============0
_index news
_type _doc
_id -Z4LB3QBhQI7S8XqvLjl
_version 1
status CREATED
=============1
_index news
_type _doc
_id NAILB3QBfZgDx-b1xOMr
_version 1
status CREATED
=============2
_index news
_type _doc
_id -p4LB3QBhQI7S8Xqx7ix
_version 1
status CREATED
=============3
_index news
_type _doc
_id NQILB3QBfZgDx-b1yeNE
_version 1
status CREATED
=============4
_index news
_type _doc
_id -54LB3QBhQI7S8Xqyrjs
_version 1
status CREATED
=============5
_index news
_type _doc
_id NgILB3QBfZgDx-b1zOMK
_version 1
status CREATED
=============6
_index news
_type _doc
_id _J4LB3QBhQI7S8XqzLjT
_version 1
status CREATED
=============7
_index news
_type _doc
_id NwILB3QBfZgDx-b1zeN9
_version 1
status CREATED
=============8
_index news
_type _doc
_id _Z4LB3QBhQI7S8Xqzrhk
_version 1
status CREATED
补充:上面的方式不会给ID赋值,ID是ES自动生成的,如果需要自己赋值,如下:
IndexRequest indexRequest = new IndexRequest("news").id((i + 1) + "").source(jsonMap);
2. Get API 根据ID查询
根据ID查询
private static void getDoc() throwsIOException {
String defaultIndex= "news";//on startup
RestHighLevelClient client = newRestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 19200, "http")));
GetRequest getRequest= new GetRequest(defaultIndex, "1");
GetResponse getResponse=client.get(getRequest, RequestOptions.DEFAULT);
String index=getResponse.getIndex();
String id=getResponse.getId();if(getResponse.isExists()) {long version =getResponse.getVersion();
String sourceAsString=getResponse.getSourceAsString();
Map sourceAsMap =getResponse.getSourceAsMap();
System.out.println(index);
System.out.println(id);
System.out.println(version);
System.out.println(sourceAsString);
System.out.println(sourceAsMap);
}else{
System.out.println("不存在");
}//on shutdown
client.close();
}
结果:
news
1
1
{"creator":"creator0","createTime":"2020-08-19T14:17:18.790Z","type":"杂文","title":"杂文记录","content":"这里是杂文记录"}
{creator=creator0, createTime=2020-08-19T14:17:18.790Z, type=杂文, title=杂文记录, content=这里是杂文记录}
3.Get Source 获取数据内容
private static void getSource() throwsIOException {
String defaultIndex= "news";//on startup
RestHighLevelClient client = newRestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 19200, "http")));
GetSourceRequest getSourceRequest= new GetSourceRequest(defaultIndex, "1");
GetSourceResponse response=client.getSource(getSourceRequest, RequestOptions.DEFAULT);
Map source =response.getSource();
System.out.println(source);//on shutdown
client.close();
}
结果:
{creator=creator0, createTime=2020-08-19T14:17:18.790Z, type=杂文, title=杂文记录, content=这里是杂文记录}
4. exists 判断存在
private static void exists() throwsIOException {
String defaultIndex= "news";//on startup
RestHighLevelClient client = newRestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 19200, "http")));
GetRequest getRequest= new GetRequest(defaultIndex, "1");//Disable fetching _source.
getRequest.fetchSourceContext(new FetchSourceContext(false));//Disable fetching stored fields.
getRequest.storedFields("_none_");boolean exists =client.exists(getRequest, RequestOptions.DEFAULT);
System.out.println(exists);//on shutdown
client.close();
}
结果:
true
5.Delete 根据ID删除
private static void delete() throwsIOException {
String defaultIndex= "news";//on startup
RestHighLevelClient client = newRestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 19200, "http")));
DeleteRequest request= new DeleteRequest(defaultIndex, "1");
DeleteResponse deleteResponse=client.delete(request, RequestOptions.DEFAULT);
String index=deleteResponse.getIndex();
String id=deleteResponse.getId();
System.out.println(index+ "\t" +id);//on shutdown
client.close();
}
结果:
news 1
6. Update根据ID修改
private static void update() throwsIOException {
String defaultIndex= "news";//on startup
RestHighLevelClient client = newRestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 19200, "http")));//修改部分字段
Map jsonMap = new HashMap<>();
jsonMap.put("content", "修改过的");
UpdateRequest request= new UpdateRequest(defaultIndex, "1").doc(jsonMap);//修改完读取数据
request.fetchSource(true);//执行修改
UpdateResponse updateResponse =client.update(request, RequestOptions.DEFAULT);
GetResult result=updateResponse.getGetResult();if(result.isExists()) {
Map sourceAsMap =result.sourceAsMap();
System.out.println(sourceAsMap);
}else{
}//on shutdown
client.close();
}
结果:
{creator=creator0, createTime=2020-08-19T14:32:37.804Z, type=杂文, title=杂文记录, content=修改过的}
补充: 用脚本更新
private static void update() throwsIOException {
String defaultIndex= "news";//on startup
RestHighLevelClient client = newRestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 19200, "http")));//多个请求.可以是相同的增加请求也可以是不同类型的请求
UpdateRequest request = new UpdateRequest(defaultIndex, "1");//修改完读取数据
request.fetchSource(true);//添加请求
Map singletonMap = new HashMap<>();
singletonMap.put("content", "append");
Script inline= new Script(ScriptType.INLINE, "painless", "ctx._source.content += params.content",
singletonMap);
request.script(inline);
UpdateResponse updateResponse=client.update(request, RequestOptions.DEFAULT);
GetResult result=updateResponse.getGetResult();if(result.isExists()) {
Map sourceAsMap =result.sourceAsMap();
System.out.println(sourceAsMap);
}else{
}//on shutdown
client.close();
}
结果:
{creator=creator0, field=nullappend, createTime=2020-08-19T14:32:37.804Z, type=杂文, title=杂文记录, content=java NP!!!!append}
6.termVector
待补充
7. bulk API 在一次请求中发送多个ES请求(增删改等)
private static void bulk() throwsIOException {
String defaultIndex= "news";//on startup
RestHighLevelClient client = newRestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 19200, "http")));//多个请求.可以是相同的增加请求也可以是不同类型的请求
BulkRequest request = newBulkRequest();//添加请求
Map jsonMap = new HashMap<>();
jsonMap.put("type", "java");
jsonMap.put("content", "java NP");
jsonMap.put("creator", "creator2");
jsonMap.put("createTime", newDate());
request.add(new IndexRequest(defaultIndex).id("2").source(jsonMap));//修改请求
Map jsonMap2 = new HashMap<>();
jsonMap2.put("content", "java NP!!!!");
request.add(new UpdateRequest(defaultIndex, "1").doc(jsonMap2));
BulkResponse bulkResponse=client.bulk(request, RequestOptions.DEFAULT);for(BulkItemResponse bulkItemResponse : bulkResponse) {
DocWriteResponse itemResponse=bulkItemResponse.getResponse();switch(bulkItemResponse.getOpType()) {caseINDEX:caseCREATE:
IndexResponse indexResponse=(IndexResponse) itemResponse;
System.out.println("create " +indexResponse);break;caseUPDATE:
UpdateResponse updateResponse=(UpdateResponse) itemResponse;
System.out.println("updateResponse " +updateResponse);break;caseDELETE:
DeleteResponse deleteResponse=(DeleteResponse) itemResponse;
}
}//on shutdown
client.close();
}
结果:
create IndexResponse[index=news,type=_doc,id=2,version=1,result=created,seqNo=2,primaryTerm=1,shards={"total":3,"successful":1,"failed":0}]
updateResponse UpdateResponse[index=news,type=_doc,id=1,version=3,seqNo=9,primaryTerm=1,result=updated,shards=ShardInfo{total=3, successful=1, failures=[]}]
8. multip-get api
private static void multiGet() throwsIOException {
String defaultIndex= "news";//on startup
RestHighLevelClient client = newRestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 19200, "http")));
MultiGetRequest request= newMultiGetRequest();
request.add(new MultiGetRequest.Item(defaultIndex, "1"));
request.add(new MultiGetRequest.Item(defaultIndex, "_J4LB3QBhQI7S8XqzLjT"));
MultiGetResponse response=client.mget(request, RequestOptions.DEFAULT);
MultiGetItemResponse[] responses=response.getResponses();if (responses != null) {for(MultiGetItemResponse responseTmp : responses) {
GetResponse response2=responseTmp.getResponse();
String index=responseTmp.getIndex();
String id=responseTmp.getId();if(response2.isExists()) {long version =response2.getVersion();
Map sourceAsMap =response2.getSourceAsMap();
System.out.println(sourceAsMap);
}else{
}
}
}//on shutdown
client.close();
}
结果:
{creator=creator0, field=nullappend, createTime=2020-08-19T14:32:37.804Z, type=杂文, title=杂文记录, content=java NP!!!!append}
{creator=creator6, createTime=2020-08-19T14:07:27.946Z, type=java, title=java记录, content=这里是java记录}
9.Reindex API
A ReindexRequest can be used to copy documents from one or more indexes into a destination index.
private static void reIndex() throwsIOException {
String defaultIndex= "news";//on startup
RestHighLevelClient client = newRestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 19200, "http")));
ReindexRequest request= newReindexRequest();
request.setSourceIndices(defaultIndex);
request.setDestIndex("news2");
request.setDestOpType("create");
request.setConflicts("proceed");
BulkByScrollResponse bulkResponse=client.reindex(request, RequestOptions.DEFAULT);
TimeValue timeTaken=bulkResponse.getTook();boolean timedOut =bulkResponse.isTimedOut();long totalDocs =bulkResponse.getTotal();long updatedDocs =bulkResponse.getUpdated();long createdDocs =bulkResponse.getCreated();long deletedDocs =bulkResponse.getDeleted();long batches =bulkResponse.getBatches();long noops =bulkResponse.getNoops();long versionConflicts =bulkResponse.getVersionConflicts();long bulkRetries =bulkResponse.getBulkRetries();long searchRetries =bulkResponse.getSearchRetries();
TimeValue throttledMillis=bulkResponse.getStatus().getThrottled();
TimeValue throttledUntilMillis=bulkResponse.getStatus().getThrottledUntil();
List searchFailures =bulkResponse.getSearchFailures();
List bulkFailures =bulkResponse.getBulkFailures();
System.out.println(totalDocs);
System.out.println(createdDocs);//on shutdown
client.close();
}
结果:
11
11
10. UpdateByQuery
private static void reIndex() throwsIOException {
String defaultIndex= "news";//on startup
RestHighLevelClient client = newRestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 19200, "http")));
UpdateByQueryRequest request= newUpdateByQueryRequest(defaultIndex);//request.setQuery(new TermQueryBuilder("creator", "creator0"));
request.setScript(new Script(ScriptType.INLINE, "painless","if (ctx._source.creator == 'creator0') {ctx._source.content='修改后的XXXXXXXX';}",
Collections.emptyMap()));//on shutdown
client.close();
}
11. DeleteByQuery
private static void deleteByQuery() throwsIOException {
String defaultIndex= "news";//on startup
RestHighLevelClient client = newRestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 19200, "http")));
DeleteByQueryRequest request= newDeleteByQueryRequest(defaultIndex);
request.setQuery(new TermQueryBuilder("creator", "creator2"));
BulkByScrollResponse bulkResponse=client.deleteByQuery(request, RequestOptions.DEFAULT);//on shutdown
client.close();
}
3.Search APIs
1. 查询
1. 查所有:
private static void search() throwsIOException {
String defaultIndex= "news";//on startup
RestHighLevelClient client = newRestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 19200, "http")));//创建SearchRequest,可以指定Index,也可以不指定。不指定查询所有
SearchRequest searchRequest = newSearchRequest(defaultIndex);//SearchRequest searchRequest = new SearchRequest(defaultIndex);
SearchSourceBuilder searchSourceBuilder = newSearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse=client.search(searchRequest, RequestOptions.DEFAULT);
SearchHits hits=searchResponse.getHits();
TotalHits totalHits=hits.getTotalHits();//the total number of hits, must be interpreted in the context of//totalHits.relation
long numHits =totalHits.value;
System.out.println("numHits " +numHits);//whether the number of hits is accurate (EQUAL_TO) or a lower bound of//the total (GREATER_THAN_OR_EQUAL_TO)
TotalHits.Relation relation =totalHits.relation;float maxScore =hits.getMaxScore();
System.out.println("maxScore " +maxScore);
SearchHit[] searchHits=hits.getHits();for(SearchHit hit : searchHits) {//do something with the SearchHit
String sourceAsString =hit.getSourceAsString();
Map sourceAsMap =hit.getSourceAsMap();
System.out.println(sourceAsMap);
}//on shutdown
client.close();
}
结果:
numHits 9
maxScore 1.0
{creator=creator5, createTime=2020-08-19T14:07:27.745Z, type=杂文, title=杂文记录, content=这里是杂文记录}
{creator=creator8, createTime=2020-08-19T14:07:28.346Z, type=js, title=js记录, content=这里是js记录}
{creator=creator4, createTime=2020-08-19T14:07:27.459Z, type=es, title=js记录, content=这里是js记录}
{creator=creator0, createTime=2020-08-19T14:07:21.696Z, type=杂文, title=杂文记录, content=修改后的XXXXXXXX}
{creator=creator1, createTime=2020-08-19T14:07:25.469Z, type=java, title=java记录, content=这里是java记录}
{creator=creator3, createTime=2020-08-19T14:07:27.034Z, type=js, title=js记录, content=这里是js记录}
{creator=creator6, createTime=2020-08-19T14:07:27.946Z, type=java, title=java记录, content=这里是java记录}
{creator=creator7, createTime=2020-08-19T14:07:28.113Z, type=vue, title=vue记录, content=这里是vue记录}
{creator=creator0, field=nullappend, createTime=2020-08-19T14:32:37.804Z, type=杂文, title=杂文记录, content=修改后的XXXXXXXX}
2. 组合条件以及分页查询、高亮显示
private static void search() throwsIOException {
String defaultIndex= "news";//on startup
RestHighLevelClient client = newRestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 19200, "http")));//创建SearchRequest,可以指定Index,也可以不指定。不指定查询所有
SearchRequest searchRequest = newSearchRequest(defaultIndex);//SearchRequest searchRequest = new SearchRequest(defaultIndex);
SearchSourceBuilder searchSourceBuilder= newSearchSourceBuilder();//查询所有//searchSourceBuilder.query(QueryBuilders.matchAllQuery());//查询type是杂文
searchSourceBuilder.query(QueryBuilders.termQuery("content", "后"));//类似于分页参数
searchSourceBuilder.from(0);
searchSourceBuilder.size(2);//排序
searchSourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC)); //分数排序
searchSourceBuilder.sort(new FieldSortBuilder("createTime").order(SortOrder.ASC));//时间升序//过滤指定的列。可以指定只搜索的列,也可以指定排除的列,也可以同时指定,同时指定include优先级高
searchSourceBuilder.fetchSource(true);
String[] includeFields= new String[] { "createTime", "innerObject.*"};
String[] excludeFields= new String[] { "title"};
searchSourceBuilder.fetchSource(null, excludeFields);//高亮
HighlightBuilder highlightBuilder = newHighlightBuilder();
HighlightBuilder.Field highlightTitle= new HighlightBuilder.Field("content");
highlightBuilder.field(highlightTitle);
searchSourceBuilder.highlighter(highlightBuilder);
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse=client.search(searchRequest, RequestOptions.DEFAULT);
SearchHits hits=searchResponse.getHits();
TotalHits totalHits=hits.getTotalHits();//the total number of hits, must be interpreted in the context of//totalHits.relation
long numHits =totalHits.value;
System.out.println("numHits " +numHits);//whether the number of hits is accurate (EQUAL_TO) or a lower bound of//the total (GREATER_THAN_OR_EQUAL_TO)
TotalHits.Relation relation =totalHits.relation;float maxScore =hits.getMaxScore();
System.out.println("maxScore " +maxScore);
SearchHit[] searchHits=hits.getHits();for(SearchHit hit : searchHits) {//do something with the SearchHit
Map highlightFields =hit.getHighlightFields();
System.out.println(highlightFields);
Map sourceAsMap =hit.getSourceAsMap();
System.out.println(sourceAsMap);
}//on shutdown
client.close();
}
结果:
numHits 2
maxScore NaN
{content=[content], fragments[[修改后的XXXXXXXX]]}
{creator=creator0, field=nullappend, createTime=2020-08-19T14:32:37.804Z, type=杂文, content=修改后的XXXXXXXX}
{content=[content], fragments[[修改后的XXXXXXXX]]}
{creator=creator0, createTime=2020-08-19T14:07:21.696Z, type=杂文, content=修改后的XXXXXXXX}
3. 使用QueryBuilder DSL语法构建查询
private static void search() throwsIOException {
String defaultIndex= "news";//on startup
RestHighLevelClient client = newRestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 19200, "http")));//创建SearchRequest,可以指定Index,也可以不指定。不指定查询所有
SearchRequest searchRequest = newSearchRequest(defaultIndex);//SearchRequest searchRequest = new SearchRequest(defaultIndex);
SearchSourceBuilder searchSourceBuilder= newSearchSourceBuilder();//可以结合Query DSL
BoolQueryBuilder filter = QueryBuilders.boolQuery().must(QueryBuilders.termQuery("content", "后"))
.mustNot(QueryBuilders.termQuery("field", "nullappend"));
searchSourceBuilder.query(filter);
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse=client.search(searchRequest, RequestOptions.DEFAULT);
SearchHits hits=searchResponse.getHits();
TotalHits totalHits=hits.getTotalHits();//the total number of hits, must be interpreted in the context of//totalHits.relation
long numHits =totalHits.value;
System.out.println("numHits " +numHits);//whether the number of hits is accurate (EQUAL_TO) or a lower bound of//the total (GREATER_THAN_OR_EQUAL_TO)
TotalHits.Relation relation =totalHits.relation;float maxScore =hits.getMaxScore();
System.out.println("maxScore " +maxScore);
SearchHit[] searchHits=hits.getHits();for(SearchHit hit : searchHits) {//do something with the SearchHit
Map sourceAsMap =hit.getSourceAsMap();
System.out.println(sourceAsMap);
}//on shutdown
client.close();
}
结果:
numHits 1
maxScore 0.8898244
{creator=creator0, createTime=2020-08-19T14:07:21.696Z, type=杂文, title=杂文记录, content=修改后的XXXXXXXX}
补充:一些常用的其他DSL查询语法
(1) 查询所有
SearchSourceBuilder searchSourceBuilder = newSearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder=QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.matchAllQuery());
searchSourceBuilder.query(boolQueryBuilder);
searchRequest.source(searchSourceBuilder);
结果:
numHits 9maxScore1.0{creator=creator1, createTime=2020-08-27T02:52:24.491Z, type=java, title=java记录, content=这里是java记录}
{creator=creator2, createTime=2020-08-27T02:52:31.677Z, type=vue, title=vue记录, content=这里是vue记录}
{creator=creator3, createTime=2020-08-27T02:52:31.915Z, type=js, title=js记录, content=这里是js记录}
{creator=creator4, createTime=2020-08-27T02:52:32.067Z, type=es, title=js记录, content=这里是js记录}
{creator=creator7, createTime=2020-08-27T02:52:33.733Z, type=vue, title=vue记录, content=这里是vue记录}
{creator=creator6, createTime=2020-08-27T02:52:32.395Z, type=java, title=java记录, content=这里是java记录}
{creator=creator0, createTime=2020-08-27T02:52:14.353Z, type=杂文, title=杂文记录, content=这里是杂文记录}
{creator=creator5, createTime=2020-08-27T02:52:32.202Z, type=杂文, title=杂文记录, content=这里是杂文记录}
{creator=creator8, createTime=2020-08-27T02:52:34.030Z, type=js, title=js记录, content=JS是真的强}
(2) 查询类型是java或者vue的-下面用的termQuery,当然可以用termsQuery
1) 不修改权重
private static void search() throwsIOException {
String defaultIndex= "news";//on startup
RestHighLevelClient client = newRestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 19200, "http")));//创建SearchRequest,可以指定Index,也可以不指定。不指定查询所有
SearchRequest searchRequest = newSearchRequest(defaultIndex);
SearchSourceBuilder searchSourceBuilder= newSearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder=QueryBuilders.boolQuery();
boolQueryBuilder.should(QueryBuilders.termQuery("type", "java"));
boolQueryBuilder.should(QueryBuilders.termQuery("type", "vue"));
searchSourceBuilder.query(boolQueryBuilder);
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse=client.search(searchRequest, RequestOptions.DEFAULT);
SearchHits hits=searchResponse.getHits();
TotalHits totalHits=hits.getTotalHits();//the total number of hits, must be interpreted in the context of//totalHits.relation
long numHits =totalHits.value;
System.out.println("numHits " +numHits);//whether the number of hits is accurate (EQUAL_TO) or a lower bound of//the total (GREATER_THAN_OR_EQUAL_TO)
TotalHits.Relation relation =totalHits.relation;float maxScore =hits.getMaxScore();
System.out.println("maxScore " +maxScore);
SearchHit[] searchHits=hits.getHits();for(SearchHit hit : searchHits) {//do something with the SearchHit
Map sourceAsMap =hit.getSourceAsMap();
System.out.println(hit.getScore()+ "\t" +sourceAsMap);
}//on shutdown
client.close();
}
结果:
numHits 4maxScore1.3862942
1.3862942 {creator=creator1, createTime=2020-08-27T02:52:24.491Z, type=java, title=java记录, content=这里是java记录}0.87546873 {creator=creator2, createTime=2020-08-27T02:52:31.677Z, type=vue, title=vue记录, content=这里是vue记录}0.87546873 {creator=creator7, createTime=2020-08-27T02:52:33.733Z, type=vue, title=vue记录, content=这里是vue记录}0.2876821 {creator=creator6, createTime=2020-08-27T02:52:32.395Z, type=java, title=java记录, content=这里是java记录}
2)修改java的权重,优先排列
SearchSourceBuilder searchSourceBuilder = newSearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder=QueryBuilders.boolQuery();
boolQueryBuilder.should(QueryBuilders.termQuery("type", "java").boost(20F));
boolQueryBuilder.should(QueryBuilders.termQuery("type", "vue"));
searchSourceBuilder.query(boolQueryBuilder);
searchRequest.source(searchSourceBuilder);
结果:
numHits 4
maxScore 41.58883
41.58883{creator=creator1, createTime=2020-08-27T02:52:24.491Z, type=java, title=java记录, content=这里是java记录}
8.630463{creator=creator6, createTime=2020-08-27T02:52:32.395Z, type=java, title=java记录, content=这里是java记录}
0.87546873{creator=creator2, createTime=2020-08-27T02:52:31.677Z, type=vue, title=vue记录, content=这里是vue记录}
0.87546873{creator=creator7, createTime=2020-08-27T02:52:33.733Z, type=vue, title=vue记录, content=这里是vue记录}
4. 聚合查询
首先修改数据都增加一个amount字段:
private static void searchUpdate() throwsIOException {
String defaultIndex= "news";//on startup
RestHighLevelClient client = newRestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 19200, "http")));//创建SearchRequest,可以指定Index,也可以不指定。不指定查询所有
SearchRequest searchRequest = newSearchRequest(defaultIndex);//SearchRequest searchRequest = new SearchRequest(defaultIndex);
SearchSourceBuilder searchSourceBuilder = newSearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse=client.search(searchRequest, RequestOptions.DEFAULT);
SearchHits hits=searchResponse.getHits();
TotalHits totalHits=hits.getTotalHits();//the total number of hits, must be interpreted in the context of//totalHits.relation
long numHits =totalHits.value;
System.out.println("numHits " +numHits);//whether the number of hits is accurate (EQUAL_TO) or a lower bound of//the total (GREATER_THAN_OR_EQUAL_TO)
TotalHits.Relation relation =totalHits.relation;float maxScore =hits.getMaxScore();
System.out.println("maxScore " +maxScore);//修改数据
SearchHit[] searchHits =hits.getHits();int num = 0;for(SearchHit hit : searchHits) {
num++;
Map sourceAsMap =hit.getSourceAsMap();
sourceAsMap.put("amount", num);
String id=hit.getId();
UpdateRequest request= newUpdateRequest(defaultIndex, id).doc(sourceAsMap);
client.update(request, RequestOptions.DEFAULT);
}//on shutdown
client.close();
}
(1) 度量聚合==统计某个数值字段的信息,数值计量聚合操作是能够产生具体的数值的一种计量聚合操作。例如查询总数:其他查询max、min、avg类似
private static void search() throwsIOException {
String defaultIndex= "news";//on startup
RestHighLevelClient client = newRestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 19200, "http")));//创建SearchRequest,可以指定Index,也可以不指定。不指定查询所有
SearchRequest searchRequest = newSearchRequest(defaultIndex);//SearchRequest searchRequest = new SearchRequest(defaultIndex);
SearchSourceBuilder searchSourceBuilder= newSearchSourceBuilder();
searchRequest.source(searchSourceBuilder);//聚合 ( text类型不能用于索引或排序d)//total 相当于是起的别名
SumAggregationBuilder aggregation = AggregationBuilders.sum("total").field("amount");
searchSourceBuilder.aggregation(aggregation);
SearchResponse searchResponse=client.search(searchRequest, RequestOptions.DEFAULT);
Sum agg= searchResponse.getAggregations().get("total");double value =agg.getValue();
System.out.println(value);//on shutdown
client.close();
}
结果:
45.0
也可以用stats直接查询所有
private static void search() throwsIOException {
String defaultIndex= "news";//on startup
RestHighLevelClient client = newRestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 19200, "http")));//创建SearchRequest,可以指定Index,也可以不指定。不指定查询所有
SearchRequest searchRequest = newSearchRequest(defaultIndex);//SearchRequest searchRequest = new SearchRequest(defaultIndex);
SearchSourceBuilder searchSourceBuilder= newSearchSourceBuilder();
searchRequest.source(searchSourceBuilder);//聚合 ( text类型不能用于索引或排序d)//stats 相当于是起的别名
StatsAggregationBuilder aggregation = AggregationBuilders.stats("stats").field("amount");
searchSourceBuilder.aggregation(aggregation);
SearchResponse searchResponse=client.search(searchRequest, RequestOptions.DEFAULT);
Stats agg= searchResponse.getAggregations().get("stats");double min =agg.getMin();double max =agg.getMax();double avg =agg.getAvg();double sum =agg.getSum();long count =agg.getCount();
System.out.println(min);
System.out.println(max);
System.out.println(avg);
System.out.println(sum);
System.out.println(count);//on shutdown
client.close();
}
结果:
1.0
9.0
5.0
45.0
9
(2) 桶分聚合=与度量聚合相比,Bucket聚合可以保存子聚合,这些子聚合将针对由其“父”bucket聚合创建的bucket进行聚合。
1) 词元聚合
private static void search() throwsIOException {
String defaultIndex= "news";//on startup
RestHighLevelClient client = newRestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 19200, "http")));//创建SearchRequest,可以指定Index,也可以不指定。不指定查询所有
SearchRequest searchRequest = newSearchRequest(defaultIndex);//SearchRequest searchRequest = new SearchRequest(defaultIndex);
SearchSourceBuilder searchSourceBuilder= newSearchSourceBuilder();
searchRequest.source(searchSourceBuilder);//聚合 ( text类型不能用于索引或排序,如果是text可以用 filed.keyword转换)。按统计的数量升序排序
TermsAggregationBuilder field = AggregationBuilders.terms("types").field("type").order(BucketOrder.count(true));
searchSourceBuilder.aggregation(field);
SearchResponse searchResponse=client.search(searchRequest, RequestOptions.DEFAULT);
Terms genders= searchResponse.getAggregations().get("types");//For each entry
for(Terms.Bucket entry : genders.getBuckets()) {
Object key= entry.getKey(); //Term
long docCount = entry.getDocCount(); //Doc count
System.out.println(key);
System.out.println(docCount);
}//on shutdown
client.close();
}
结果:
es
1
vue
1
java
2
js
2
杂文
3
2) 词元聚合+子聚合实现求总数、均值
private static void search() throwsIOException {
String defaultIndex= "news";//on startup
RestHighLevelClient client = newRestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 19200, "http")));//创建SearchRequest,可以指定Index,也可以不指定。不指定查询所有
SearchRequest searchRequest = newSearchRequest(defaultIndex);//SearchRequest searchRequest = new SearchRequest(defaultIndex);
SearchSourceBuilder searchSourceBuilder= newSearchSourceBuilder();
searchRequest.source(searchSourceBuilder);//聚合 ( text类型不能用于索引或排序,如果是text可以用 filed.keyword转换)。按统计的数量升序排序
TermsAggregationBuilder field = AggregationBuilders.terms("types").field("type").order(BucketOrder.count(true));
field.subAggregation(AggregationBuilders.avg("avg_amount").field("amount"));
searchSourceBuilder.aggregation(field);
SearchResponse searchResponse=client.search(searchRequest, RequestOptions.DEFAULT);
Terms types_agg= searchResponse.getAggregations().get("types");//For each entry
List extends Bucket> buckets =types_agg.getBuckets();for(Terms.Bucket entry : buckets) {
Object key= entry.getKey(); //Term
long docCount = entry.getDocCount(); //Doc count
System.out.println(key + "\t" +docCount);
Avg average= entry.getAggregations().get("avg_amount");
System.out.println("均值: \t" +average.getValue());
}//on shutdown
client.close();
}
结果:
es 1
均值: 3.0
vue1
均值: 8.0
java2
均值: 6.0
js2
均值: 4.0
杂文3
均值: 4.666666666666667
2. MultiSearch
private static void search() throwsIOException {
String defaultIndex= "news";//on startup
RestHighLevelClient client = newRestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 19200, "http")));//创建SearchRequest,可以指定Index,也可以不指定。不指定查询所有
MultiSearchRequest request = newMultiSearchRequest();
SearchRequest firstSearchRequest= newSearchRequest(defaultIndex);
SearchSourceBuilder searchSourceBuilder= newSearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchQuery("type", "java"));
firstSearchRequest.source(searchSourceBuilder);
request.add(firstSearchRequest);
SearchRequest secondSearchRequest= newSearchRequest(defaultIndex);
searchSourceBuilder= newSearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchQuery("type", "vue"));
secondSearchRequest.source(searchSourceBuilder);
request.add(secondSearchRequest);
MultiSearchResponse response=client.msearch(request, RequestOptions.DEFAULT);
Item[] responses=response.getResponses();for(Item responseTmp : responses) {
System.out.println("===============");
SearchResponse searchResponse=responseTmp.getResponse();
doPrint(searchResponse);
}//on shutdown
client.close();
}private static voiddoPrint(SearchResponse searchResponse) {
SearchHits hits=searchResponse.getHits();
TotalHits totalHits=hits.getTotalHits();//the total number of hits, must be interpreted in the context of//totalHits.relation
long numHits =totalHits.value;
System.out.println("numHits " +numHits);//whether the number of hits is accurate (EQUAL_TO) or a lower bound of//the total (GREATER_THAN_OR_EQUAL_TO)
TotalHits.Relation relation =totalHits.relation;float maxScore =hits.getMaxScore();
System.out.println("maxScore " +maxScore);
SearchHit[] searchHits=hits.getHits();for(SearchHit hit : searchHits) {//do something with the SearchHit
Map sourceAsMap =hit.getSourceAsMap();
System.out.println(sourceAsMap);
}
}
结果:
===============
numHits 2
maxScore 0.87546873
{creator=creator6, amount=7, createTime=2020-08-19T14:07:27.946Z, type=java, title=java记录, content=这里是java记录}
{creator=creator1, amount=5, createTime=2020-08-19T14:07:25.469Z, type=java, title=java记录, content=这里是java记录}
===============
numHits 1
maxScore 1.3862942
{creator=creator7, amount=8, createTime=2020-08-19T14:07:28.113Z, type=vue, title=vue记录, content=这里是vue记录}
3.Count 查询数量
private static void search() throwsIOException {
String defaultIndex= "news";//on startup
RestHighLevelClient client = newRestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 19200, "http")));
CountRequest countRequest= newCountRequest();
countRequest.indices(defaultIndex);//创建查询条件
SearchSourceBuilder sourceBuilder = newSearchSourceBuilder();
sourceBuilder.query(QueryBuilders.termQuery("type", "java"));
countRequest.source(sourceBuilder);
CountResponse countResponse=client.count(countRequest, RequestOptions.DEFAULT);long count =countResponse.getCount();
System.out.println("count " +count);
RestStatus status=countResponse.status();
System.out.println("status " +status);
Boolean terminatedEarly=countResponse.isTerminatedEarly();
System.out.println("terminatedEarly " +terminatedEarly);int totalShards =countResponse.getTotalShards();
System.out.println("totalShards " +totalShards);int skippedShards =countResponse.getSkippedShards();
System.out.println("skippedShards " +skippedShards);int successfulShards =countResponse.getSuccessfulShards();
System.out.println("successfulShards " +successfulShards);int failedShards =countResponse.getFailedShards();
System.out.println("failedShards " +failedShards);if (countResponse.getShardFailures() != null) {for(ShardSearchFailure failure : countResponse.getShardFailures()) {//failures should be handled here
}
}//on shutdown
client.close();
}
结果:
count 2
status OK
terminatedEarly null
totalShards 3
skippedShards 0
successfulShards 3
failedShards 0
补充:AnalyzerAPI可以用于分析分词效果,用不同的分词器进行分词,例如:
private static void anylyze() throwsIOException {//on startup
RestHighLevelClient client = newRestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http")));
AnalyzeRequest request= AnalyzeRequest.withGlobalAnalyzer("standard", "我是一个程序员", "I am cxy!");
request.explain(true);
AnalyzeResponse response=client.indices().analyze(request, RequestOptions.DEFAULT);
DetailAnalyzeResponse detail=response.detail();
AnalyzeTokenList analyzer=detail.analyzer();
String name=analyzer.getName();
System.out.println(name);
System.out.println("==============");
AnalyzeToken[] tokens1=analyzer.getTokens();for(AnalyzeToken t : tokens1) {
System.out.println(t.getTerm()+ "\t" + t.getStartOffset() + "\t" + t.getEndOffset() + "\t" +t.getType());
}//on shutdown
client.close();
}
结果:
standard
==============
我01
是12
一23
个34
程45
序56
员67
i89
am1012
cxy1316
用ik_smart分词分析效果如下:
org.wltea.analyzer.lucene.IKAnalyzer
==============
我01CN_CHAR
是12CN_CHAR
一个24CN_WORD
程序员47CN_WORD
i89ENGLISH
am1012ENGLISH
cxy1316ENGLISH
补充:ES的text字段不能聚合,需要用keyword字段进行聚合