搜索引擎(ES-Java-client-api)

學完本課題,你應達成以下目標:

瞭解ES提供了哪些客戶端,及客戶的DOC文檔連接。
掌握Java REST client 的使用。
掌握Java client 的使用。html

ES Client 簡介

ES是一個服務,採用C/S結構java

回顧 ES的架構node

ES支持的客戶端鏈接方式git

 REST API ,端口 9200
 Transport 鏈接    端口 9300github

ES提供了多種編程語言客戶端spring

Client api 學習連接 https://www.elastic.co/guide/en/elasticsearch/client/index.html編程

 

Java REST Client

ES提供了兩個JAVA REST client 版本json

Java Low Level REST Client: 低級別的REST客戶端,經過http與集羣交互,用戶需本身編組請求JSON串,及解析響應JSON串。兼容全部ES版本。
Java High Level REST Client: 高級別的REST客戶端,基於低級別的REST客戶端,增長了編組請求、解析響應等相關api。api

Java Low Level REST Client 說明數組

特色,maven 引入、使用介紹請參閱:
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-low.html

API doc 請參閱:
https://artifacts.elastic.co/javadoc/org/elasticsearch/client/elasticsearch-rest-client/6.2.4/index.html.

從6.0.0開始加入的,目的是以java面向對象的方式來進行請求、響應處理。
每一個API 支持 同步/異步 兩種方式,同步方法直接返回一個結果對象。異步的方法以 async 爲後綴,經過listener 參數來通知結果。
高級java REST 客戶端依賴Elasticsearch core project

兼容性說明

依賴 java1.8  和 Elasticsearch core project
請使用與服務端ES版本一致的客戶端版本

Java High Level REST Client  maven 集成

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

Java High Level REST Client  初始化

RestHighLevelClient client = new RestHighLevelClient(
        RestClient.builder(
                new HttpHost("localhost", 9200, "http"),
                new HttpHost("localhost", 9201, "http")));

給定集羣的多個節點地址,將客戶端負載均衡地向這個節點地址集發請求

Client 再也不使用了,記得關閉它。

client.close();

API

API及用法示例,請參考:

https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-supported-apis.html

Create index

public class CreateIndexDemo {

	public static void main(String[] args) {
		try (RestHighLevelClient client = InitDemo.getClient();) {

			// 一、建立 建立索引request
			CreateIndexRequest request = new CreateIndexRequest("mess");

			// 二、設置索引的settings
			request.settings(Settings.builder().put("index.number_of_shards", 3) // 分片數
					.put("index.number_of_replicas", 2) // 副本數
					.put("analysis.analyzer.default.tokenizer", "ik_smart") // 默認分詞器
			);

			// 三、設置索引的mappings
			request.mapping("_doc",
					"  {\n" +
				    "    \"tweet\": {\n" +
				    "      \"properties\": {\n" +
				    "        \"message\": {\n" +
				    "          \"type\": \"text\"\n" +
				    "        }\n" +
				    "      }\n" +
				    "    }\n" +
				    "  }",
					XContentType.JSON);

			// 四、 設置索引的別名
			request.alias(new Alias("mmm"));

			// 五、 發送請求
			// 5.1 同步方式發送請求
			CreateIndexResponse createIndexResponse = client.indices()
					.create(request);

			// 六、處理響應
			boolean acknowledged = createIndexResponse.isAcknowledged();
			boolean shardsAcknowledged = createIndexResponse
					.isShardsAcknowledged();
			System.out.println("acknowledged = " + acknowledged);
			System.out.println("shardsAcknowledged = " + shardsAcknowledged);

			// 5.1 異步方式發送請求
			/*ActionListener<CreateIndexResponse> listener = new ActionListener<CreateIndexResponse>() {
				@Override
				public void onResponse(
						CreateIndexResponse createIndexResponse) {
					// 六、處理響應
					boolean acknowledged = createIndexResponse.isAcknowledged();
					boolean shardsAcknowledged = createIndexResponse
							.isShardsAcknowledged();
					System.out.println("acknowledged = " + acknowledged);
					System.out.println(
							"shardsAcknowledged = " + shardsAcknowledged);
				}

				@Override
				public void onFailure(Exception e) {
					System.out.println("建立索引異常:" + e.getMessage());
				}
			};

			client.indices().createAsync(request, listener);
			*/
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

代碼庫地址:http://code.dongnaoedu.com/3266399810/vip-elasticsearch/tree/master/es-hrset-client

index  document

public class IndexDocumentDemo {
	
	private static Logger logger = LogManager.getRootLogger();  

	public static void main(String[] args) {
		try (RestHighLevelClient client = InitDemo.getClient();) {
			// 一、建立索引請求
			IndexRequest request = new IndexRequest(
			        "mess",   //索引
			        "_doc",     // mapping type
			        "1");     //文檔id  
			
			// 二、準備文檔數據
			// 方式一:直接給JSON串
			String jsonString = "{" +
			        "\"user\":\"kimchy\"," +
			        "\"postDate\":\"2013-01-30\"," +
			        "\"message\":\"trying out Elasticsearch\"" +
			        "}";
			request.source(jsonString, XContentType.JSON); 
			
			// 方式二:以map對象來表示文檔
			/*
			Map<String, Object> jsonMap = new HashMap<>();
			jsonMap.put("user", "kimchy");
			jsonMap.put("postDate", new Date());
			jsonMap.put("message", "trying out Elasticsearch");
			request.source(jsonMap); 
			*/
			
			// 方式三:用XContentBuilder來構建文檔
			/*
			XContentBuilder builder = XContentFactory.jsonBuilder();
			builder.startObject();
			{
			    builder.field("user", "kimchy");
			    builder.field("postDate", new Date());
			    builder.field("message", "trying out Elasticsearch");
			}
			builder.endObject();
			request.source(builder); 
			*/
			
			// 方式四:直接用key-value對給出
			/*
			request.source("user", "kimchy",
			                "postDate", new Date(),
			                "message", "trying out Elasticsearch");
			*/
			
			//三、其餘的一些可選設置
			/*
			request.routing("routing");  //設置routing值
			request.timeout(TimeValue.timeValueSeconds(1));  //設置主分片等待時長
			request.setRefreshPolicy("wait_for");  //設置重刷新策略
			request.version(2);  //設置版本號
			request.opType(DocWriteRequest.OpType.CREATE);  //操做類別  
			*/
			
			//四、發送請求
			IndexResponse indexResponse = null;
			try {
				// 同步方式
				indexResponse = client.index(request);			
			} catch(ElasticsearchException e) {
				// 捕獲,並處理異常
				//判斷是否版本衝突、create但文檔已存在衝突
			    if (e.status() == RestStatus.CONFLICT) {
			    	logger.error("衝突了,請在此寫衝突處理邏輯!\n" + e.getDetailedMessage());
			    }
			    
			    logger.error("索引異常", e);
			}
			
			//五、處理響應
			if(indexResponse != null) {
				String index = indexResponse.getIndex();
				String type = indexResponse.getType();
				String id = indexResponse.getId();
				long version = indexResponse.getVersion();
				if (indexResponse.getResult() == DocWriteResponse.Result.CREATED) {
				    System.out.println("新增文檔成功,處理邏輯代碼寫到這裏。");
				} else if (indexResponse.getResult() == DocWriteResponse.Result.UPDATED) {
				    System.out.println("修改文檔成功,處理邏輯代碼寫到這裏。");
				}
				// 分片處理信息
				ReplicationResponse.ShardInfo shardInfo = indexResponse.getShardInfo();
				if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
				    
				}
				// 若是有分片副本失敗,能夠得到失敗緣由信息
				if (shardInfo.getFailed() > 0) {
				    for (ReplicationResponse.ShardInfo.Failure failure : shardInfo.getFailures()) {
				        String reason = failure.reason(); 
				        System.out.println("副本失敗緣由:" + reason);
				    }
				}
			}
			
			
			//異步方式發送索引請求
			/*ActionListener<IndexResponse> listener = new ActionListener<IndexResponse>() {
			    @Override
			    public void onResponse(IndexResponse indexResponse) {
			        
			    }

			    @Override
			    public void onFailure(Exception e) {
			        
			    }
			};
			client.indexAsync(request, listener);
			*/
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

get  document

public class GetDocumentDemo {
	
	private static Logger logger = LogManager.getRootLogger();  

	public static void main(String[] args) {
		try (RestHighLevelClient client = InitDemo.getClient();) {
			// 一、建立索引請求
			GetRequest request = new GetRequest(
			        "mess",   //索引
			        "_doc",     // mapping type
			        "1");     //文檔id  
			
			// 二、可選的設置
			//request.routing("routing");
			//request.version(2);
			
			//request.fetchSourceContext(new FetchSourceContext(false)); //是否獲取_source字段
			//選擇返回的字段
			String[] includes = new String[]{"message", "*Date"};
			String[] excludes = Strings.EMPTY_ARRAY;
			FetchSourceContext fetchSourceContext = new FetchSourceContext(true, includes, excludes);
			request.fetchSourceContext(fetchSourceContext); 
			
			//也可寫成這樣
			/*String[] includes = Strings.EMPTY_ARRAY;
			String[] excludes = new String[]{"message"};
			FetchSourceContext fetchSourceContext = new FetchSourceContext(true, includes, excludes);
			request.fetchSourceContext(fetchSourceContext);*/
			
			
			// 取stored字段
			/*request.storedFields("message"); 
			GetResponse getResponse = client.get(request);
			String message = getResponse.getField("message").getValue();*/
			
			
			//三、發送請求		
			GetResponse getResponse = null;
			try {
				// 同步請求
			    getResponse = client.get(request);
			} catch (ElasticsearchException e) {
			    if (e.status() == RestStatus.NOT_FOUND) {
			    	logger.error("沒有找到該id的文檔" );
			    }
			    if (e.status() == RestStatus.CONFLICT) {
			    	logger.error("獲取時版本衝突了,請在此寫衝突處理邏輯!" );
			    }
			    logger.error("獲取文檔異常", e);
			}
			
			//四、處理響應
			if(getResponse != null) {
				String index = getResponse.getIndex();
				String type = getResponse.getType();
				String id = getResponse.getId();
				if (getResponse.isExists()) { // 文檔存在
				    long version = getResponse.getVersion();
				    String sourceAsString = getResponse.getSourceAsString(); //結果取成 String       
				    Map<String, Object> sourceAsMap = getResponse.getSourceAsMap();  // 結果取成Map
				    byte[] sourceAsBytes = getResponse.getSourceAsBytes();    //結果取成字節數組
				    
				    logger.info("index:" + index + "  type:" + type + "  id:" + id);
				    logger.info(sourceAsString);
				    
				} else {
					logger.error("沒有找到該id的文檔" );
				}
			}
			
			
			//異步方式發送索引請求
			/*
			ActionListener<GetResponse> listener = new ActionListener<GetResponse>() {
			    @Override
			    public void onResponse(GetResponse getResponse) {
			        
			    }
			
			    @Override
			    public void onFailure(Exception e) {
			        
			    }
			};
			client.getAsync(request, listener);
			*/
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

Bulk

public class BulkDemo {
	
	private static Logger logger = LogManager.getRootLogger();  

	public static void main(String[] args) {
		try (RestHighLevelClient client = InitDemo.getClient();) {
			
			// 一、建立批量操做請求
			BulkRequest request = new BulkRequest(); 
			request.add(new IndexRequest("mess", "_doc", "1")  
			        .source(XContentType.JSON,"field", "foo"));
			request.add(new IndexRequest("mess", "_doc", "2")  
			        .source(XContentType.JSON,"field", "bar"));
			request.add(new IndexRequest("mess", "_doc", "3")  
			        .source(XContentType.JSON,"field", "baz"));
			
			/*
			request.add(new DeleteRequest("mess", "_doc", "3")); 
			request.add(new UpdateRequest("mess", "_doc", "2") 
			        .doc(XContentType.JSON,"other", "test"));
			request.add(new IndexRequest("mess", "_doc", "4")  
			        .source(XContentType.JSON,"field", "baz"));
			*/
			
			// 二、可選的設置
			/*
			request.timeout("2m");
			request.setRefreshPolicy("wait_for");  
			request.waitForActiveShards(2);
			*/
			
			
			//三、發送請求		
		
			// 同步請求
			BulkResponse bulkResponse = client.bulk(request);
			
			
			//四、處理響應
			if(bulkResponse != null) {
				for (BulkItemResponse bulkItemResponse : bulkResponse) { 
				    DocWriteResponse itemResponse = bulkItemResponse.getResponse(); 

				    if (bulkItemResponse.getOpType() == DocWriteRequest.OpType.INDEX
				            || bulkItemResponse.getOpType() == DocWriteRequest.OpType.CREATE) { 
				        IndexResponse indexResponse = (IndexResponse) itemResponse;
				        //TODO 新增成功的處理

				    } else if (bulkItemResponse.getOpType() == DocWriteRequest.OpType.UPDATE) { 
				        UpdateResponse updateResponse = (UpdateResponse) itemResponse;
				       //TODO 修改爲功的處理

				    } else if (bulkItemResponse.getOpType() == DocWriteRequest.OpType.DELETE) { 
				        DeleteResponse deleteResponse = (DeleteResponse) itemResponse;
				        //TODO 刪除成功的處理
				    }
				}
			}
			
			
			//異步方式發送批量操做請求
			/*
			ActionListener<BulkResponse> listener = new ActionListener<BulkResponse>() {
			    @Override
			    public void onResponse(BulkResponse bulkResponse) {
			        
			    }
			
			    @Override
			    public void onFailure(Exception e) {
			        
			    }
			};
			client.bulkAsync(request, listener);
			*/
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

search

public class SearchDemo {
	
	private static Logger logger = LogManager.getRootLogger();  

	public static void main(String[] args) {
		try (RestHighLevelClient client = InitDemo.getClient();) {
			
			// 一、建立search請求
			//SearchRequest searchRequest = new SearchRequest();
			SearchRequest searchRequest = new SearchRequest("bank"); 
			searchRequest.types("_doc");
			
			// 二、用SearchSourceBuilder來構造查詢請求體 ,請仔細查看它的方法,構造各類查詢的方法都在這。
			SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); 
			
			//構造QueryBuilder
			/*QueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("user", "kimchy")
                    .fuzziness(Fuzziness.AUTO)
                    .prefixLength(3)
                    .maxExpansions(10);
			sourceBuilder.query(matchQueryBuilder);*/
			
			sourceBuilder.query(QueryBuilders.termQuery("age", 24)); 
			sourceBuilder.from(0); 
			sourceBuilder.size(10); 
			sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS)); 
			
			//是否返回_source字段
			//sourceBuilder.fetchSource(false);
			
			//設置返回哪些字段
			/*String[] includeFields = new String[] {"title", "user", "innerObject.*"};
			String[] excludeFields = new String[] {"_type"};
			sourceBuilder.fetchSource(includeFields, excludeFields);*/
			
			//指定排序
			//sourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC)); 
			//sourceBuilder.sort(new FieldSortBuilder("_uid").order(SortOrder.ASC));
			
			// 設置返回 profile 
			//sourceBuilder.profile(true);
			
			//將請求體加入到請求中
			searchRequest.source(sourceBuilder);
			
			// 可選的設置
			//searchRequest.routing("routing");
			
			// 高亮設置
			/*
			HighlightBuilder highlightBuilder = new HighlightBuilder(); 
			HighlightBuilder.Field highlightTitle =
			        new HighlightBuilder.Field("title"); 
			highlightTitle.highlighterType("unified");  
			highlightBuilder.field(highlightTitle);  
			HighlightBuilder.Field highlightUser = new HighlightBuilder.Field("user");
			highlightBuilder.field(highlightUser);
			sourceBuilder.highlighter(highlightBuilder);*/
			
			
			//加入聚合
			/*TermsAggregationBuilder aggregation = AggregationBuilders.terms("by_company")
			        .field("company.keyword");
			aggregation.subAggregation(AggregationBuilders.avg("average_age")
			        .field("age"));
			sourceBuilder.aggregation(aggregation);*/
			
			//作查詢建議
			/*SuggestionBuilder termSuggestionBuilder =
				    SuggestBuilders.termSuggestion("user").text("kmichy"); 
				SuggestBuilder suggestBuilder = new SuggestBuilder();
				suggestBuilder.addSuggestion("suggest_user", termSuggestionBuilder); 
			sourceBuilder.suggest(suggestBuilder);*/
			
			//三、發送請求		
			SearchResponse searchResponse = client.search(searchRequest);
			
			
			//四、處理響應
			//搜索結果狀態信息
			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
			}
			
			//處理搜索命中文檔結果
			SearchHits hits = searchResponse.getHits();
			
			long totalHits = hits.getTotalHits();
			float maxScore = hits.getMaxScore();
			
			SearchHit[] searchHits = hits.getHits();
			for (SearchHit hit : searchHits) {
			    // do something with the SearchHit
				
				String index = hit.getIndex();
				String type = hit.getType();
				String id = hit.getId();
				float score = hit.getScore();
				
				//取_source字段值
				String sourceAsString = hit.getSourceAsString(); //取成json串
				Map<String, Object> sourceAsMap = hit.getSourceAsMap(); // 取成map對象
				//從map中取字段值
				/*
				String documentTitle = (String) sourceAsMap.get("title"); 
				List<Object> users = (List<Object>) sourceAsMap.get("user");
				Map<String, Object> innerObject = (Map<String, Object>) sourceAsMap.get("innerObject");
				*/
				logger.info("index:" + index + "  type:" + type + "  id:" + id);
			    logger.info(sourceAsString);
			    
				//取高亮結果
				/*Map<String, HighlightField> highlightFields = hit.getHighlightFields();
			    HighlightField highlight = highlightFields.get("title"); 
			    Text[] fragments = highlight.fragments();  
			    String fragmentString = fragments[0].string();*/
			}
			
			// 獲取聚合結果
			/*
			Aggregations aggregations = searchResponse.getAggregations();
			Terms byCompanyAggregation = aggregations.get("by_company"); 
			Bucket elasticBucket = byCompanyAggregation.getBucketByKey("Elastic"); 
			Avg averageAge = elasticBucket.getAggregations().get("average_age"); 
			double avg = averageAge.getValue();
			*/
			
			// 獲取建議結果
			/*Suggest suggest = searchResponse.getSuggest(); 
			TermSuggestion termSuggestion = suggest.getSuggestion("suggest_user"); 
			for (TermSuggestion.Entry entry : termSuggestion.getEntries()) { 
			    for (TermSuggestion.Entry.Option option : entry) { 
			        String suggestText = option.getText().string();
			    }
			}
			*/
			
			//異步方式發送獲查詢請求
			/*
			ActionListener<SearchResponse> listener = new ActionListener<SearchResponse>() {
			    @Override
			    public void onResponse(SearchResponse getResponse) {
			        //結果獲取
			    }
			
			    @Override
			    public void onFailure(Exception e) {
			        //失敗處理
			    }
			};
			client.searchAsync(searchRequest, listener); 
			*/
			
		} catch (IOException e) {
			logger.error(e);
		}
	}
}

highlight

public class HighlightDemo {
	
	private static Logger logger = LogManager.getRootLogger();  

	public static void main(String[] args) {
		try (RestHighLevelClient client = InitDemo.getClient();) {
			
			// 一、建立search請求
			SearchRequest searchRequest = new SearchRequest("hl_test"); 
			
			// 二、用SearchSourceBuilder來構造查詢請求體 ,請仔細查看它的方法,構造各類查詢的方法都在這。
			SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); 
			
			//構造QueryBuilder
			QueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", "lucene solr");
			sourceBuilder.query(matchQueryBuilder);
			
			//分頁設置
			/*sourceBuilder.from(0); 
			sourceBuilder.size(5); ;*/ 
			
					
			// 高亮設置
			HighlightBuilder highlightBuilder = new HighlightBuilder(); 
			highlightBuilder.requireFieldMatch(false).field("title").field("content")
				.preTags("<strong>").postTags("</strong>");
			//不一樣字段可有不一樣設置,如不一樣標籤
			/*HighlightBuilder.Field highlightTitle = new HighlightBuilder.Field("title"); 
			highlightTitle.preTags("<strong>").postTags("</strong>");
			highlightBuilder.field(highlightTitle);  
			HighlightBuilder.Field highlightContent = new HighlightBuilder.Field("content");
			highlightContent.preTags("<b>").postTags("</b>");
			highlightBuilder.field(highlightContent).requireFieldMatch(false);*/
			
			sourceBuilder.highlighter(highlightBuilder);
			
			searchRequest.source(sourceBuilder);
			
			//三、發送請求		
			SearchResponse searchResponse = client.search(searchRequest);
			
			
			//四、處理響應
			if(RestStatus.OK.equals(searchResponse.status())) {
				//處理搜索命中文檔結果
				SearchHits hits = searchResponse.getHits();
				long totalHits = hits.getTotalHits();
				
				SearchHit[] searchHits = hits.getHits();
				for (SearchHit hit : searchHits) {		
					String index = hit.getIndex();
					String type = hit.getType();
					String id = hit.getId();
					float score = hit.getScore();
					
					//取_source字段值
					//String sourceAsString = hit.getSourceAsString(); //取成json串
					Map<String, Object> sourceAsMap = hit.getSourceAsMap(); // 取成map對象
					//從map中取字段值
					/*String title = (String) sourceAsMap.get("title"); 
					String content  = (String) sourceAsMap.get("content"); */
					logger.info("index:" + index + "  type:" + type + "  id:" + id);
				    logger.info("sourceMap : " +  sourceAsMap);
					//取高亮結果
					Map<String, HighlightField> highlightFields = hit.getHighlightFields();
				    HighlightField highlight = highlightFields.get("title"); 
				    if(highlight != null) {
					    Text[] fragments = highlight.fragments();  //多值的字段會有多個值
					    if(fragments != null) {
					    	String fragmentString = fragments[0].string();
					    	logger.info("title highlight : " +  fragmentString);
					    	//可用高亮字符串替換上面sourceAsMap中的對應字段返回到上一級調用
					    	//sourceAsMap.put("title", fragmentString);
					    }
				    }
				    
				    highlight = highlightFields.get("content"); 
				    if(highlight != null) {
					    Text[] fragments = highlight.fragments();  //多值的字段會有多個值
					    if(fragments != null) {
					    	String fragmentString = fragments[0].string();
					    	logger.info("content highlight : " +  fragmentString);
					    	//可用高亮字符串替換上面sourceAsMap中的對應字段返回到上一級調用
					    	//sourceAsMap.put("content", fragmentString);
					    }
				    }
				}
			}
			
		} catch (IOException e) {
			logger.error(e);
		}
	}
}

suggest

public class SuggestDemo {
	
	private static Logger logger = LogManager.getRootLogger();  
	
	public static void termSuggest() {
		try (RestHighLevelClient client = InitDemo.getClient();) {
			
			// 一、建立search請求
			//SearchRequest searchRequest = new SearchRequest();
			SearchRequest searchRequest = new SearchRequest("mess"); 
			
			// 二、用SearchSourceBuilder來構造查詢請求體 ,請仔細查看它的方法,構造各類查詢的方法都在這。
			SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); 
			 
			sourceBuilder.size(0); 
			
			//作查詢建議		
			//詞項建議
			SuggestionBuilder termSuggestionBuilder =
				    SuggestBuilders.termSuggestion("user").text("kmichy"); 
			SuggestBuilder suggestBuilder = new SuggestBuilder();
			suggestBuilder.addSuggestion("suggest_user", termSuggestionBuilder); 	
			sourceBuilder.suggest(suggestBuilder);
			
			searchRequest.source(sourceBuilder);	
			
			//三、發送請求		
			SearchResponse searchResponse = client.search(searchRequest);
			
			
			//四、處理響應
			//搜索結果狀態信息
			if(RestStatus.OK.equals(searchResponse.status())) {
				// 獲取建議結果
				Suggest suggest = searchResponse.getSuggest(); 
				TermSuggestion termSuggestion = suggest.getSuggestion("suggest_user"); 
				for (TermSuggestion.Entry entry : termSuggestion.getEntries()) { 
					logger.info("text: " + entry.getText().string());
				    for (TermSuggestion.Entry.Option option : entry) { 
				        String suggestText = option.getText().string();
				        logger.info("   suggest option : " + suggestText);
				    }
				}
			}
			/*
			  "suggest": {
			    "my-suggestion": [
			      {
			        "text": "tring",
			        "offset": 0,
			        "length": 5,
			        "options": [
			          {
			            "text": "trying",
			            "score": 0.8,
			            "freq": 1
			          }
			        ]
			      },
			      {
			        "text": "out",
			        "offset": 6,
			        "length": 3,
			        "options": []
			      },
			      {
			        "text": "elasticsearch",
			        "offset": 10,
			        "length": 13,
			        "options": []
			      }
			    ]
			  }*/

		} catch (IOException e) {
			logger.error(e);
		}
	}
	
	public static void completionSuggester() {
		try (RestHighLevelClient client = InitDemo.getClient();) {
			
			// 一、建立search請求
			//SearchRequest searchRequest = new SearchRequest();
			SearchRequest searchRequest = new SearchRequest("music"); 
			
			// 二、用SearchSourceBuilder來構造查詢請求體 ,請仔細查看它的方法,構造各類查詢的方法都在這。
			SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); 
			 
			sourceBuilder.size(0); 
			
			//作查詢建議		
			//自動補全
			/*POST music/_search?pretty
					{
					    "suggest": {
					        "song-suggest" : {
					            "prefix" : "lucene s", 
					            "completion" : { 
					                "field" : "suggest" ,
					                "skip_duplicates": true
					            }
					        }
					    }
					}*/

			SuggestionBuilder termSuggestionBuilder =
				    SuggestBuilders.completionSuggestion("suggest").prefix("lucene s")
				    .skipDuplicates(true); 
			SuggestBuilder suggestBuilder = new SuggestBuilder();
			suggestBuilder.addSuggestion("song-suggest", termSuggestionBuilder); 	
			sourceBuilder.suggest(suggestBuilder);
			
			searchRequest.source(sourceBuilder);	
			
			//三、發送請求		
			SearchResponse searchResponse = client.search(searchRequest);
			
			
			//四、處理響應
			//搜索結果狀態信息
			if(RestStatus.OK.equals(searchResponse.status())) {
				// 獲取建議結果
				Suggest suggest = searchResponse.getSuggest(); 
				CompletionSuggestion termSuggestion = suggest.getSuggestion("song-suggest"); 
				for (CompletionSuggestion.Entry entry : termSuggestion.getEntries()) { 
					logger.info("text: " + entry.getText().string());
				    for (CompletionSuggestion.Entry.Option option : entry) { 
				        String suggestText = option.getText().string();
				        logger.info("   suggest option : " + suggestText);
				    }
				}
			}

		} catch (IOException e) {
			logger.error(e);
		}
	}

	public static void main(String[] args) {
		termSuggest();
		
		logger.info("--------------------------------------");
		
		completionSuggester();
	}
}

aggregation

public class AggregationDemo {
	
	private static Logger logger = LogManager.getRootLogger();  

	public static void main(String[] args) {
		try (RestHighLevelClient client = InitDemo.getClient();) {
			
			// 一、建立search請求
			//SearchRequest searchRequest = new SearchRequest();
			SearchRequest searchRequest = new SearchRequest("bank"); 
			
			// 二、用SearchSourceBuilder來構造查詢請求體 ,請仔細查看它的方法,構造各類查詢的方法都在這。
			SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); 
			 
			sourceBuilder.size(0); 

			//加入聚合
			//字段值項分組聚合
			TermsAggregationBuilder aggregation = AggregationBuilders.terms("by_age")
			        .field("age").order(BucketOrder.aggregation("average_balance", true));
			//計算每組的平均balance指標
			aggregation.subAggregation(AggregationBuilders.avg("average_balance")
			        .field("balance"));
			sourceBuilder.aggregation(aggregation);
			
			searchRequest.source(sourceBuilder);
			
			//三、發送請求		
			SearchResponse searchResponse = client.search(searchRequest);
				
			//四、處理響應
			//搜索結果狀態信息
			if(RestStatus.OK.equals(searchResponse.status())) {
				// 獲取聚合結果
				Aggregations aggregations = searchResponse.getAggregations();
				Terms byAgeAggregation = aggregations.get("by_age"); 
				logger.info("aggregation by_age 結果");
				logger.info("docCountError: " + byAgeAggregation.getDocCountError());
				logger.info("sumOfOtherDocCounts: " + byAgeAggregation.getSumOfOtherDocCounts());
				logger.info("------------------------------------");
				for(Bucket buck : byAgeAggregation.getBuckets()) {
					logger.info("key: " + buck.getKeyAsNumber());
					logger.info("docCount: " + buck.getDocCount());
					logger.info("docCountError: " + buck.getDocCountError());
					//取子聚合
					Avg averageBalance = buck.getAggregations().get("average_balance"); 

					logger.info("average_balance: " + averageBalance.getValue());
					logger.info("------------------------------------");
				}
				//直接用key 來去分組
				/*Bucket elasticBucket = byCompanyAggregation.getBucketByKey("24"); 
				Avg averageAge = elasticBucket.getAggregations().get("average_age"); 
				double avg = averageAge.getValue();*/
				
			}
			
		} catch (IOException e) {
			logger.error(e);
		}
	}
}public class AggregationDemo {
	
	private static Logger logger = LogManager.getRootLogger();  

	public static void main(String[] args) {
		try (RestHighLevelClient client = InitDemo.getClient();) {
			
			// 一、建立search請求
			//SearchRequest searchRequest = new SearchRequest();
			SearchRequest searchRequest = new SearchRequest("bank"); 
			
			// 二、用SearchSourceBuilder來構造查詢請求體 ,請仔細查看它的方法,構造各類查詢的方法都在這。
			SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); 
			 
			sourceBuilder.size(0); 

			//加入聚合
			//字段值項分組聚合
			TermsAggregationBuilder aggregation = AggregationBuilders.terms("by_age")
			        .field("age").order(BucketOrder.aggregation("average_balance", true));
			//計算每組的平均balance指標
			aggregation.subAggregation(AggregationBuilders.avg("average_balance")
			        .field("balance"));
			sourceBuilder.aggregation(aggregation);
			
			searchRequest.source(sourceBuilder);
			
			//三、發送請求		
			SearchResponse searchResponse = client.search(searchRequest);
				
			//四、處理響應
			//搜索結果狀態信息
			if(RestStatus.OK.equals(searchResponse.status())) {
				// 獲取聚合結果
				Aggregations aggregations = searchResponse.getAggregations();
				Terms byAgeAggregation = aggregations.get("by_age"); 
				logger.info("aggregation by_age 結果");
				logger.info("docCountError: " + byAgeAggregation.getDocCountError());
				logger.info("sumOfOtherDocCounts: " + byAgeAggregation.getSumOfOtherDocCounts());
				logger.info("------------------------------------");
				for(Bucket buck : byAgeAggregation.getBuckets()) {
					logger.info("key: " + buck.getKeyAsNumber());
					logger.info("docCount: " + buck.getDocCount());
					logger.info("docCountError: " + buck.getDocCountError());
					//取子聚合
					Avg averageBalance = buck.getAggregations().get("average_balance"); 

					logger.info("average_balance: " + averageBalance.getValue());
					logger.info("------------------------------------");
				}
				//直接用key 來去分組
				/*Bucket elasticBucket = byCompanyAggregation.getBucketByKey("24"); 
				Avg averageAge = elasticBucket.getAggregations().get("average_age"); 
				double avg = averageAge.getValue();*/
				
			}
			
		} catch (IOException e) {
			logger.error(e);
		}
	}
}

各類查詢對應的QueryBuilder

https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-query-builders.html

各類聚合對應的AggregationBuilder

https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-aggregation-builders.html

Java Client

Java Client 說明

java client 使用 TransportClient,各類操做本質上都是異步的(能夠用 listener,或返回 Future )。 
注意:ES的發展規劃中在7.0版本開始將廢棄 TransportClient,8.0版本中將徹底移除 TransportClient,取而代之的是High Level REST Client。
High Level REST Client 中的操做API和java client 大可能是同樣的。

官方學習連接

https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/index.html

兼容性說明

請使用與服務端ES版本一致的客戶端版本

Java Client  maven 集成

<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>transport</artifactId>
    <version>6.2.4</version>
</dependency>

依賴的其餘jar和high REST Client基本同樣

Java Client  logger 日誌器說明

使用的是 log4j2 日誌組件。
若是要使用其餘的日誌組件,可以使用slf4j做橋

Init Client

// on startup
Settings settings = Settings.builder()
        .put("cluster.name", "myClusterName").build();      /鏈接集羣的設置
TransportClient client = new PreBuiltTransportClient(settings)
        .addTransportAddress(new TransportAddress(InetAddress.getByName("host1"), 9300))
        .addTransportAddress(new TransportAddress(InetAddress.getByName("host2"), 9300));
                                                          //鏈接的transport地址,注意端口是9300
// on shutdown

client.close();   //在關閉時記得關閉客戶端對象

Init Client setting 可用參數說明

cluster.name
        指定集羣的名字,若是集羣的名字不是默認的elasticsearch,需指定。
client.transport.sniff
        設置爲true,將自動嗅探整個集羣,自動加入集羣的節點到鏈接列表中。
client.transport.ignore_cluster_name
        Set to true to ignore cluster name validation of connected nodes. (since 0.19.4)
client.transport.ping_timeout
        The time to wait for a ping response from a node. Defaults to 5s.
client.transport.nodes_sampler_interval
        How often to sample / ping the nodes listed and connected. Defaults to 5s.

Document API 文檔操做API

官網詳細介紹連接: https://www.elastic.co/guide/en/elasticsearch/client/java-api/6.2/java-docs.html

Search API

https://www.elastic.co/guide/en/elasticsearch/client/java-api/6.2/java-search.html

代碼示例: es-java-client  地址

http://code.dongnaoedu.com/3266399810/vip-elasticsearch/tree/master/

Spring Data Elasticsearch 學習連接

https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/ https://github.com/spring-projects/spring-data-elasticsearch.  

相關文章
相關標籤/搜索