elasticsearch透過建構一個client對外提供了一套豐富的java呼叫介面。整體來說client分成兩類cluster資訊方面的client及資料(index)方面的client。這兩個大類由可以分為通用操作和admin操作兩類。
(1.5版本,其它版本可能不一樣):
透過這個繼承關係圖可以很清楚的了解client的實現,及功能。總共有三類即client, indicesAdminClient和ClusterAdminClient。它都有自己的實作類,但最後都是透過client介面對外提供服務。 client作為對外的總接口,首先透過admin()方法組合了admin的相關操作,它本身也提供了所有對資料和cluster的通用操作。
所有的介面都透過兩種方式實作了非同步調用,一個是傳回一個ActionFuture,另一個方法是接受一個ActionListener。
如下圖
ActionFuture
index(IndexRequest request) ; void index(IndexRequest request , ActionListener
listener);
第一個方法會傳回一個future,第二個方法則需要傳遞一個Listener。這也是非同步實現的兩個基本方式。 client使用了門面模式,所有的實作都在AbstractClient類別中,也以index方法為例,程式碼如下所示:
@Override public ActionFuture<IndexResponse> index(final IndexRequest request) { return execute(IndexAction.INSTANCE, request); } @Override public void index(final IndexRequest request, final ActionListener<IndexResponse> listener) { execute(IndexAction.INSTANCE, request, listener); }
實作如上所示,之所以說它是門面模式是因為所有的方法都被整合到了client中,但是執行過程都是在對應的action中執行。在execute方法中,取得到對應的action實例,真正的邏輯是在對應的transportaction中實作。
如下:
@SuppressWarnings("unchecked") @Override public <Request extends ActionRequest, Response extends ActionResponse, RequestBuilder extends ActionRequestBuilder<Request, Response, RequestBuilder, Client>> ActionFuture<Response> execute(Action<Request, Response, RequestBuilder, Client> action, Request request) { headers.applyTo(request); TransportAction<Request, Response> transportAction = actions.get((ClientAction)action); return transportAction.execute(request); } @SuppressWarnings("unchecked") @Override public <Request extends ActionRequest, Response extends ActionResponse, RequestBuilder extends ActionRequestBuilder<Request, Response, RequestBuilder, Client>> void execute(Action<Request, Response, RequestBuilder, Client> action, Request request, ActionListener<Response> listener) { headers.applyTo(request); TransportAction<Request, Response> transportAction = actions.get((ClientAction)action); transportAction.execute(request, listener); }
每個動作都對應有對應的transportAction,而這些transportAction才是最終的執行者。這裡先以index為例簡單說明,在後面索引功能分析會看到更多這種的結果。
public class IndexAction extends ClientAction<IndexRequest, IndexResponse, IndexRequestBuilder> { public static final IndexAction INSTANCE = new IndexAction(); public static final String NAME = "indices:data/write/index"; private IndexAction() { super(NAME); } @Override public IndexResponse newResponse() { return new IndexResponse(); } @Override public IndexRequestBuilder newRequestBuilder(Client client) { return new IndexRequestBuilder(client); } }
在IndexAction中只是簡單的定義了一個NAME,及幾個簡單的方法。這個名字會在啟動時作為對於的transportHandler的key註冊到TransportService中。在execute方法中,會根據action的將transportAction取出如上一段程式碼所示。真正的執行邏輯在InternalTransportClient中,這裡先略過它的實現,後面會有詳細分析。所有這些action的註冊都是在actionModule中實現,註冊過程會在後面跟著action一起分析。
以上是如何使用Java建立Elasticsearch客戶端並呼叫API?的詳細內容。更多資訊請關注PHP中文網其他相關文章!