1.Elasticsearch中Java API的簡介
Elasticsearch 的Java API 提供了非常便捷的方法來索引和查詢數據等。 通過添加jar包,不需要編寫HTTP層的代碼就可以開始着手進行連接到Elasticsearch的工作。它提供了兩種方法連接到Elasticsearch:創建一個本地節點並加入集群(cluster),或者利用傳輸(transport)。這兩種方法都是利用一個Client(org.elasticsearch.client.Client)實例來實現的。
2.兩種連接方法的說明和比較
使用第一種方法的思想,是講創建的本地節點作為集群的一部分,這樣這個創建的本地節點就可以是知道整個集群的情況,比如relevant shard是如何分配的已經如何進行高效的查詢。
Node node = nodeBuilder().clusterName("escluster2").client(true).node();
Client client = node.client();
使用NodeBuilder來創建一個node,使用clusterName()方法來指定我們想要連接的集群。為了避免本地節點關機后集群將shard移動到本地節點,從而造成數據丟失的情況,我們需要client(true);
第二種方法:通過ImmutableSettings我們設置了希望連接的集群的名稱,接下來創建了一個TransportClient,通過建立InetSocketTransportAddress實例來提供Elasticsearch server所在的IP地址已經傳輸層的監聽端口(JAVA API 默認9300,並非REST API的9200 )。
Settings settings = ImmutableSettings.settingsBuilder() .put("cluster.name", "escluster2").build(); TransportClient client = new TransportClient(settings); client.addTransportAddress(new InetSocketTransportAddress("127.0.0.1", 9300));
關於兩種方法的選擇,第一種方法:建立本地節點會需要一些時間,但是在執行一些操作的事情會節省很多時間,因為本地階段知道整個集群中indice和shard情況。 第二種方法:建立TransportClient是比較高效的,但是發送查詢信息以及數據就需要更多的資源,因為TransportClient不清楚整個集群的拓撲,所以她不能直接將數據發送到目的節點,而是發送至一個初始化后的transport節點,ElasticSearch完成接下來的轉發。 注意::如果需要連接到不用網絡中的Elasticsearch集群,就必須使用第二種方法(TransportClient對象)。
3.Client的查詢設置
Client是與集群進行通信的關鍵,而prepareXXX等函數返回一個Binder(org.elasticsearch.action.get.GetRequestBuilder)對象來方便我們設置參數。設置之后我們可以使用request()方法來保存這個request以便將來使用,或者使用execute()方法來立即執行一次查詢。
由於Elasticsearch是天生異步的,執行execute后會在等到查詢結果之前就返回caller block,所以我們可以簡單的使用actionGet()方法來阻塞程序直到查詢結構返回。
GetResponse response = client .prepareGet("library", "book", "1") .setFields("title", "_source") .execute().actionGet();
4.query舉例
public class ElasticSearchClient { private static Client client = null; private static Properties elasticsearch_properties = new Properties(); private static String PATH = ElasticSearchClient.class.getClassLoader().getResource("elasticsearch.properties").getPath(); private static String HOST = "elasticsearch.host"; private static String PORT = "elasticsearch.port"; public static void main(String[] args) { ElasticSearchClient client = new ElasticSearchClient(); client.init(); client.query(); client.close(); } public void init() { client = new TransportClient() .addTransportAddress(new InetSocketTransportAddress("YOURHOSTNAME",9300)); System.out.println("TransportClient: " + client.toString()); } public void query() { //匹配所有 //QueryBuilder queryBuilder = QueryBuilders.matchAllQuery(); //設置查詢條件 QueryBuilder queryBuilder = QueryBuilders.disMaxQuery() .add(QueryBuilders.termQuery("cmd-statistic", "http.avg5")); .add(QueryBuilders.prefixQuery("info-type", "statistic")); //System.out.println(queryBuilder.toString()); SearchResponse response = client.prepareSearch("INDEXNAME") .setQuery(queryBuilder).execute().actionGet(); for (SearchHit hit : response.getHits().getHits()) { System.out.println("---->>hit.getId(): " + hit.getId()); if (hit.getFields().containsKey("cmd-statistic")) { System.out.println("field.cmd-statistic: " + hit.getFields().get("cmd-statistic").getValue()); } System.out.println("cmd-statistic: " + hit.getSource().get("cmd-statistic")); } } public void close() { try { client.close(); } catch (Exception e) { e.printStackTrace(); }finally { try { client.close(); } catch (Exception e2) { e2.printStackTrace(); } } } }
SearchHit類代表了一個滿足查詢條件的document,獲得SearchHit后可以通過便利來輸出每一個hit的信息。addFiled()方法定義了需要返回的域。
