第08章 Elasticsearch Java API

來源:互聯網
上載者:User

標籤:option   忽略   port   類方法   listener   連接埠   sync   import   擷取   

本章內容
使用用戶端對象(client object)串連到本地或遠程Elasticsearch叢集。
逐條或批量索引文檔。
更新文檔內容。
使用各種Elasticsearch支援的查詢方式。
處理Elasticsearch返回的錯誤資訊。
通過發送各種管理指令來收集叢集狀態資訊或執行管理工作。

8.3 串連到叢集8.3.1 成為Elasticsearch節點

第一種串連到Elasticsearch節點的方式是把應用程式當成Elasticsearch叢集中的一個節點。

Node node=nodeBuilder().clusterName("escluster2").client (true).node();Client client=node.client();
8.3.2 使用傳輸機串連方式
Settings settings = ImmutableSettings.settingsBuilder().put("cluster.name","escluster2").build();TransportClient client=new TransportClient(settings);client.addTransportAddress(new InetSocketTransportAddress("127.0.0.1",9300));

注意這裡的連接埠號碼不是9200,而是9300。 9200連接埠用來讓HTTP REST API訪問Elasticsearch,而9300連接埠是傳輸層監聽的預設連接埠。
我們再回過頭來看TransportClient類的可用配置:

  • client.transport.sniff(預設值:false):如果設為true , Elasticsearch會讀取叢集中的 節點資訊。因此你不需要在建立TransportClient對象時提供所有節點的網路地址。 Elasticsearch很智能,它會自動檢測到活躍節點並把它們加人到列表中。
  • client.transport.ignore_cluster_name(預設值:false ):如果設為true,則Elasticsearch會忽視配置中的叢集名稱並嘗試串連到某個可串連叢集上,而不管叢集名稱是否匹配。這一點很危險,你可能會首先串連到你不想要的叢集上。
  • client.transport.ping_timeout(預設值:5s):該參數指定了ping命令響應的逾時時間。 如果用戶端和叢集間的網路延遲較大或串連不穩定,可能需要調大這個取值。
  • client.transport.nodes_sampler_interval預設值:5s):該參數指定了檢查節點可用 性的時間間隔。與前一個參數類似,如果網路延遲較大或者網路不穩定,可能需要調大這個值。
8.3.3 選擇合適的串連方式

第一種方式讓 啟動順序複雜化了,即用戶端節點必須加人叢集並建立與其他節點的串連,而這需要時間和資源。然而,操作卻可以更快地執行,因為所有關於叢集、索引、分區的資訊都對用戶端節點可見。

另一方面,使用TransportClient對象啟動速度更快,需要的資源更少,如更少的socket串連。然而,發送查詢和資料卻需要消耗更多的資源,TransportClient對象對 叢集和索引拓撲結構的資訊一無所知,所以它無法把資料直接發送到正確的節點,而是先把資料發給某個初始傳輸節點,然後再由Elasticsearch來完成剩下的轉寄工作。此外,TransportClient對象還需要你提供一份待串連節點的網路地址清單。

在選擇合適的串連方式時請記住,第一種方式並不總是可行的。例如,當要串連的Elasticsearch叢集處於另一個區域網路中,唯一可選的方式就是使用TransportClient對象。

8.4 API部析
  • 擷取特定文檔記錄
GetResponse response=client.prepareGet(”library","book",”1").setFields("title",”_source").execute().actionGet();

在完成準備工作之後,我們用構造器對象建立一個請求 (利用request()方法)以備隨後使用,或者直接通過execute()調用送出查詢請求,這裡我們選擇後者。

ELasticSearch的API是天生非同步。這意味著execute()調用 不會等待Elasticsearch的響應結果,而是直接把控制權交回給調用它的程式碼片段,而查詢請求在後台執行。本例中我們使用actionGet()方法,這個方法會等待查詢執行完畢並返回資料。這樣做比較簡單,但在更複雜的系統中這顯然不夠。接下來是一個使用非同步API的例子。首先引人相關聲明:

ListenableActionFuture<GetResponse> future=client.prepareGet("library","book","1").setFields("title",”_source").execute();future.addListener( new ActionListener<GetResponse>(){  @Override  public void onResponse(GetResponse response){    System.out.println("Document:"+response.getIndex()       +”/“       +response .getType()       +”/"       +response.getId());    }  @Override  public void onFailure(Throwable e){      throw new RuntimeException(e);  }});
8.5 CRUD操作8.5.1 讀取文檔
GetResponse response=client.prepareGet("library","book","1").setFields("title","_source").execute().actionGet();
  • GetRequestBuilder的方法
setFields(String):setIndex(String) , setType(String) , setId(String):setRouting(String):setParent(String):setPreference(String): 【_local, _primary】setRefresh(Boolean): 【false】setRealtime(Boolean):【true】
  • 響應GetResponse的方法
isExists():getindex():getType():getId():getVersion():isSourceEmpty():getSourceXXX():【getSourceAsString(),getSourceAsMap(),getSourceAsBytes()】getField(String):
8.5.2 索引文檔
IndexResponae response=client.prepareIndex("library","book","2")  .setSource("{\"title\":\"Mastering Elasticsearch\"}")  .execute().actionGet();
  • 構造器對象提供了如下方法:
setSource():setlndex(String), setType(String), setId(String):setRouting(String) , setParent(String):setOpType():【index,create】setRefresh(Boolean):【false】setReplicationType():【sync,async,default】setConsistencyLevel():【DEFAULT,ONE,QUORUM,ALL】多少副本活躍才進行該操作setVersion(long):多虧了這個方法。程式可以確保在讀取和更新文檔期間沒有別人更改這個文檔。setVersionType(VersionType):setPercolate(String):setTimestamp(String):setTTL(long):超過這個時間長度後文檔會被自動刪除getlndex():返回請求的索引名稱getType():返迴文檔類型名稱getId():返回被索引文檔的IDgetVersion():返回被索引文檔的版本號碼getMatches():返回匹配被索引文檔的過濾器查詢列表,如果沒有匹配的查詢,則返回null
8.5.3 更新文檔
Map<String, Object>params=Maps.newHashMap();params.put("ntitle","Elasticsearch Server Book");UpdateResponse response = client.prepareUpdate("library","book","2")  .setScript("ctx._source.title=ntitle")  .setScriptParams(params)  .execute().actionGet();
  • UpdateRequestBuilder 方法
setIndex(String) , setType(String) , setId(String):setRouting(String), setParent(String):setScript(String):setScriptLang(String):setScriptParams(Map<String, Object>):addScriptParam(String, Object):setFields(String...):setRetryOnConflict(int):預設值為0。在Elasticsearch中,更新一個文檔意味著先檢索出文檔的舊版本,修改它的結構,從索引中刪除舊版本然後重新索引新版本。這意味著,在檢索出舊版本和寫人新版本之間,目的文件可能被其他程式修改。Elasticsearch通過比較文檔版本號碼來檢測修改,如果發現修改則返回錯誤。除了直接返回錯誤,還可以選擇重試本操作。而這個重試次數就可以由本方法指定。setRefresh(Boolean):【false】setRepliactionType():【sync, async, default】。本方法用於控制在更新過程中的複製類型。預設情況下,只有所有副本執行更新後才認為更新操作是成功的,對應這裡的取值為sync或等價枚舉值。另一種選擇是不等待副本上的操作完成就直接返回,對應取值為async或等價枚舉值。還有一種選擇是讓Elasticsearch根據節點配置來決定如何操作,對應取值為default或等價枚舉值。setConsistencyLevel():【DEFAULT,ONE,QUORUM,ALL】本方法設定有多少個活躍副本時才能夠執行更新操作。setPercolate(String):這個方法將導致索引文檔要經過percolator的檢查,其參數是 一個用來限制percolator查詢的查詢串。取值為`*`表示所有查詢都要檢查。setDoc():這類方法用來設定文檔片段,而這些文檔片段將合并到索引中相同ID的 文檔上。如果通過setScript()方法設定了script,則文檔將被忽略。Elasticsearch提供了本方法的多種版本,分別需要輸入字串、位元組數組、XContentBuilder, Map 等多種類型表示的文檔。setSource():setDocsAsUpsert(Boolean):預設值為false。設定為true後,如果指定文檔在索引中不存在,則setDoc()方法使用的文檔將作為新文檔加人到索引中。 
  • 更新要求返回的響應為一個UpdateResponse對象方法:
getIndex():getType():getld():getVersion():getMatches():getGetResult():
8.5.4 刪除文檔
DeleteResponse response=client.prepareDelete("library","book","2")    .execute().actionGet();
  • DeleteRequestBuilder 方法
setIndex(String), setType(String), setId(String):setRouting(String), setParent(String):setRefresh(Boolean):setVersion(long):本方法指定索引時被刪除文檔的版本號碼。如果指定ID的文檔不 存在,或者版本號碼不匹配,則刪除操作會失敗。這個方法確保了程式中沒有別人更改這個文檔。 setVersionType(VersionType):本方法告知Elasticsearch使用哪個版本類型。setRepliactionType():【sync, async和default】setConsistencyLevel():本方法設定有多少個活躍副本時才能夠執行更新操作。【DEFAULT,ONE,QUORUM,ALL】
  • 刪除操作的響應DeleteResponse類提供了如下方法:
getIndex():返回請求的索引名稱。getType():返迴文檔類別名稱。getId():返回被索引文檔的ID。getVersion():返回被索引文檔的版本號碼。isNotFound():如果請求未找到待刪除文檔,則返回true
8.6 Elasticsearch查詢8.6.1 準備查詢請求
SearchResponse response=client.prepareSearch("library"    .addFields(‘title","_source")    .execute().actionGet();for(SearchHit hit:response.getHits().getHits()){  System.out.println(hit.getId());  if (hit.getFields().containsKey("title"}){      System.out.println("field.title: "                            +hit.getFields().get("title").getValue())    }      System.out.println("source.title: "                             +hit.getSource().get("title"));     }
8.6.2 構造查詢
QueryBuilder queryBuilder=QueryBuilders    .disMaxQuery()      .add(QueryBuilders.termQuery("title","Elastic"))      .add(QueryBuilders.prefixQuery("title","el"));System.out.println(queryBuilder.toString());SearchResponse response=client.prepareSearch("library")  .setQuery(queryBuilder)  .execute().actionGet();

匹配查詢

queryBuilder=QueryBuilders    .matchQuery("message","a quick brown fox")    .operator(Operator.AND)    .zeroTermsQuery(ZeroTermsQuery.ALL);

使用地理位置查詢

queryBuilder = QueryBuilders.geoShapeQuery("location",  ShapeBuilder.newRectangle()      .topLeft(13, 53)      .bottomRight(14, 52)    .build());
8.6.3 分頁
SearchResponse response=client.prepareSearch("library")  .setQuery(QueryBuilders.matchAllQuery())    .setFrom(10)    .setSize(20)    .execute().actionGet();
8.6.4 排序
SearchResponse response=client.prepareSearch("library")  .setQuery(QueryBuilders.matchAllQuery())  .addSort(SortBuilders.fieldSort("title"))  .addsort("_score",SortOrder .DESC)  .execute().actionGet();

除了上述排序方法外,ElasticSearcb還提供了一種基於指令碼的排序方法:scriptSort(String, String),以及一種基於空間距離排序的方法:geoDistanceSort(String).

8.6.5 過濾
FilterBuilder filterBuilder=FilterBuilders  .andFilter(     FilterBuilders .existsFilter("title").filterName("exist”),     FilterBuilders.termFilter("title","elastic")  );SearchResponse response=client.prepareSearch("library")  .setFilter(filterBuilder)  .execute().actionGet();
8.6.6 切面計算
FacetSBuilder facetBuilder=FacetBuilders  .filterFacet("test")  .filter(FilterBuilders .termFilter("title","elastic"));SearchResponse response=client.prepareSearch("library")  .addFacet(facetBuilder)  .execute()actionGet();
8.6.7 高亮
SearchResponse response=client.preparesearch("wikipedia")  .addHighlightedField("title")  .setQuery(QueryBuilders.termQuery("title","actress"))  .setHighlighterPreTags("<1>", "<2>")  .setHighlighterPostTags("</1>"," </2>").execute().actionGet();
  • 高亮處理
for(SearchHit hit:response.getHits().getHits()){  HighlightField hField = hit.getHighlightFields()get("title");  for (Text t:hField.fragments()){    System.out.println(t.string());  }}
8.6.8 查詢建議
SearchResponse response=client.prepareSearch("wikipedia")  .setQuery(QueryBuilders.matchAllQuery())  .addSuggestion(new TermSuggestionBuilder("first_suggestion")      .text("graphics designer")      .field("_all")  )  .execute().actionGet()
  • 結果處理
for(Entry<? extends Option> entry: response.getSuggest()  .getSuggestion("first_suggestion").getEntries()){    System.out.println("Check for: "      +entry.getText()      +". Options:");  for(Option option: entry.getOptions()){    System.out.println("\t"+option.getText());  }
8.6.9 計數

有時 候,我們不在乎具體會返回哪些文檔,而只想知道匹配的結果數量。在這種情況下,我們需要使用計數請求,因為它的效能更好:不需要做排序,也不需要從索引中取出文檔。

CountResponse response=client.prepareCount("library")  .setQuery(QueryBuilders.termQuery("title","elastic"))  .execute().actionGet();
8.6.10 滾動

要使用Elasticsearch Java API的滾動功能擷取大量文檔集合:

SearchResponse responseSearch=client.prepareSearch("library" )  .setScroll("1m")  .setSearchType(SearchType.SCAN)  .execute().actionGet();String scrolled=responseSearch.getScrollId();SearchResponse response = client.prepareSearchScroll(scrollld)  .execute().actionGet(),

其中有兩個請求:第一個請求指定了查詢條件以及滾動屬性,如滾動的有效時間長度(使用 setScroll()方法);第二個請求指定了查詢類型,如這裡我們切換到掃描模式(scan mode)。掃描模式下會忽略排序而僅執行取出文檔操作。

8.7 批量執行多個操作8.7.1 大量操作
BulkResponse response=client.prepareBulk()    .add(client.prepareIndex("library", "book","5")      .setSource("{\"title\":\"Solr Cookbook\"}"  .request()  .add(client.prepareDelete("library", "book", "2").request()).execute().actionGet();

該請求向Iibrary索引的boo(類型中添加了一個文檔(ID為5),又從這個索引中刪除了一 個文檔(ID為2)。得到響應後,通過getItems()方法可得到一個由org.elasticsearch.action.bulk.BulkItemResponse對象組成的數組。

8.7.2 根據查詢刪除文檔
DeleteByQueryResponse response=client.prepareDeleteByQuery("library")  .setQuery(QueryBuilders.termQuery("title","Elasticsearch"))  .execute().actionGet();
8.7.3 Multi GET
MultiGetResponse response = client.prepareMultiGet()    .add("library", "book", "1","2")    .execute().actionGet();

這個請求的響應對象包含一個getResponses()方法,而該方法返回了一個由org. elasticsearch.action.get.MultiGetItemResponse對象構成的數組。

8.7.4 Multi Search
MultiSearchResponse response=client.prepareMultiSearch()  .add(client.prepareSearch("library","book").request())  .add(client.prepareSearch("news").  .setFilter(FilterBuilders.termFilter("tags", "important")))  .execute().actionGet();

本操作包含一個getResponses()方法。該方法返回了一個由 elasticsearch.action.search.MultiSearchResponse.Item對象組成的數組。

8.8 Percolator

percolator是查詢的逆過程。我們可以根據某個文檔來找出與之匹配的所有查詢。假 定有一個prc ltr的索引,我們可以使用如下代碼向_percolator索引的prcltr類型索引一個查詢:

client.prepareIndex(”_percolator","prcltr","query:1")  .setSource(XContentFactory.jsonBuilder()      .startObject()      .field("query",              QueryBuilders .termQuery("test","abc"))              .endObject())      .execute().actionGet();

本例中我們定義了一個ID為“query: 1”的查詢,用來檢查test欄位中是否包含abc這個 值。既然percolator已經準備好了,那麼可以使用如下程式碼片段來向它發送一個文檔:

PercolateResponse response =client.preparePercolate("prcltr","type")    .setSource(XContentFactory.jsonBuilder()      .startObject()        .startObject("doc")        .field("test").value("abc")        .endObject()      .endObject())    .execute().actionGet();

我們發送的這個文檔應該是與percolator中儲存的那個查詢匹配,這一點可以通過 getMatches()方法來檢驗。具體可以使用如下代碼:

for (String match:response.getMatches()){  System.out.println("Match:"+match);}
8.9 explain API

最後一個關於查詢Elasticsearch的API是explain API。explain API可以協助檢查關於 相關度的問題,並指出文檔匹配與否的依據。請看下面的代碼:

ExplainResponse response=client  .prepareExplain(“library","book","1")      .setQuery(QueryBuilders.termQuery("title","elastic"))      .execute().actionGet();
8.11 管理API

Elasticsearch把管理操作劃分為 兩類:叢集管理和索引管理。我們先看第一類。

8.11.1 叢集管理API
ClusterAdminClient cluster=client.admin().cluster()

叢集和索引健康狀態API

ClusterHealthResponse response=client.admin().cluster()  .prepareHealth("library")  .execute().actionGet();

在響應中,可以讀取到叢集狀態、已指派分區數、總分區數、特定 索引的副本數等資訊。

叢集狀態API
叢集狀態API可以讓我們擷取叢集相關資訊,如路由、分區分配情況以及映射等。

ClusterStateResponse response=client.admin().cluster()    .prepareState()    .execute().actionGet();

設定更新API
設定更新API可以設定叢集範圍的配置參數。

Map<String, Object> map=Maps.newHashMap()map.put("indices.ttl.interval","10m");ClusterUpdateSettingsResponse response=client.admin().cluster()  .prepareUpdateSettings()  .setTransientSettings(map)  .execute().actionGet();

重新路由API
重新路由API可以在節點間移動分區,以及取消或強制進行分區分配行為。

ClusterRerouteResponse response=client .admin().cluster()  .prepareReroute()      .setDryRun(true)      .add(        new MoveAllocationCommand(new ShardId("library",3),                              "G3czOt4HQbKZT1RhpPCULw",                                PvHtEMuRSJ6rLJ27AW3U6w"),        new CancelAllocationCommand(new ShardId("‘library", 2),                              "G3czOt4HQbKZT1RhpPCULw",                               true))  .execute().actionGet();

節點資訊API
節點資訊(nodes information) API提供了一個或多個特定節點的資訊。該API輸出的資訊涵蓋Java虛擬機器、
作業系統以及網路(如IP地址或區域網路地址以及外掛程式資訊等)。

NodesInfoResponse response = client.admin().cluster()    .prepareNodesInfo()      .setNetwork(true)      .setPlugin(true)    .execute().actionGet();

節點統計API
節點統計(node statistics ) API和節點資訊API很相似,只是它輸出的是有關 Elasticsearch使用方式的資訊,如索引統計、檔案系統、HTTP模組、Java虛擬機器等。

NodesStatsResponse response=client.admin().cluster()    .prepareNodesStats()    .all()    .execute().actionGet();

節點熱點線程API
節點熱點線程API用於在Elasticsearch出故障或CPU使用率超過正常值時檢查節點狀 態。

NodesHotThreadsResponse response=client.admin().cluster()  .prepareNodesHotThreads()  .execute().actionGet();

節點關閉API
節點關閉(node shutdown ) APl比較簡單,它允許我們關閉指定節點(或所有節點)。 如果需要,還可以設定關閉延遲時間。例如,下面代碼將立即關閉整個叢集:

NodeaShutdownResponse response=client.admin().cluster()  .prepareNodesShutdown()  .execute().actionGet();

查詢分區API
查詢分區(searchshard ) API也比較簡單,它允許我們檢查哪些節點將用於處理查詢。 它還可以設定路由參數,因此在使用自訂路由時特別方便。

ClusterSearchShardsResponse response=client.admin().cluster()    .prepareSearchShards()      .setIndices("library")      .setRouting("12")    .execute().actionGet();
8.11.2 索引管理API
IndicesAdminClient cluster = client.admin().indices();

索引存在API

類型存在API

索引統計API
索引統計(indicesstats ) API可以提供關於索引、文檔、儲存以及操作的資訊,如擷取、 查詢、索引、預熱器、合并過程、清空緩衝區、重新整理等。

索引狀態

索引段資訊API

建立索引API

刪除索引API

關閉索引API

開啟索引API

重新整理API

清空緩衝區API

索引最佳化API

設定映射API

刪除映射API

別名API

擷取別名API

別名存在API

清空緩衝API

更新設定API

分析API

設定模板API

刪除模板API

查詢驗證API

設定預熱器API

刪除預熱器API

第08章 Elasticsearch Java API

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.