elasticsearch 口水篇(4)java客戶端 - 原生esClient

上一篇(elasticsearch 口水篇(3)java客戶端 - Jest)Jest是第三方客戶端,基於REST Api進行調用(httpClient),本篇簡單介紹下elasticsearch原生的java客戶端。html

具體參考:java

http://www.elasticsearch.org/guide/en/elasticsearch/client/java-api/current/node

 

下面咱們作一個很簡單的實例,如下幾個功能:json

1)批量添加1000個user對象;api

2)經過name進行查詢;dom

 

package com.fox.c1;

import java.io.IOException;

import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;

/**
 * @author huangfox
 * @date 2014年2月10日 下午3:27:43
 *
 */
public class ESClient {

	private Client client;

	public void init() {
		client = new TransportClient()
				.addTransportAddress(new InetSocketTransportAddress(
						"localhost", 9300));
	}

	public void close() {
		client.close();
	}

	/**
	 * index
	 */
	public void createIndex() {
		for (int i = 0; i < 1000; i++) {
			User user = new User();
			user.setId(new Long(i));
			user.setName("huang fox " + i);
			user.setAge(i % 100);
			client.prepareIndex("users", "user").setSource(generateJson(user))
					.execute().actionGet();
		}
	}

	/**
	 * 轉換成json對象
	 * 
	 * @param user
	 * @return
	 */
	private String generateJson(User user) {
		String json = "";
		try {
			XContentBuilder contentBuilder = XContentFactory.jsonBuilder()
					.startObject();
			contentBuilder.field("id", user.getId() + "");
			contentBuilder.field("name", user.getName());
			contentBuilder.field("age", user.getAge() + "");
			json = contentBuilder.endObject().string();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return json;
	}

	public static void main(String[] args) {
		ESClient client = new ESClient();
		client.init();
		client.createIndex();
		client.close();
	}

}

  

這裏有兩點須要注意下:elasticsearch

1)NodeClinet 和 TransportClientide

Instantiating a node based client is the simplest way to get a Client that can execute operations against elasticsearch.post

The TransportClient connects remotely to an elasticsearch cluster using the transport module. It does not join the cluster, but simply gets one or more initial transport addresses and communicates with them in round robin fashion on each action (though most actions will probably be "two hop" operations).ui

2)generate json document

There are different way of generating JSON document:

  • Manually (aka do it yourself) using native byte[] or as a String
  • Using Map that will be automatically converted to its JSON equivalent
  • Using a third party library to serialize your beans such as Jackson
  • Using built-in helpers XContentFactory.jsonBuilder()

 

------------------------------------------------

search

public void search() {
		SearchResponse response = client.prepareSearch("users")
				.setTypes("user")
				.setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
				.setQuery(QueryBuilders.termQuery("name", "fox")) // Query
				.setFilter(FilterBuilders.rangeFilter("age").from(20).to(30)) // Filter
				.setFrom(0).setSize(60).setExplain(true).execute().actionGet();
		SearchHits hits = response.getHits();
		System.out.println(hits.getTotalHits());
		for (int i = 0; i < hits.getHits().length; i++) {
			System.out.println(hits.getHits()[i].getSourceAsString());
		}
	}

  

這兩篇簡單應用了esClient和jest,至於二者的區別目前尚未定論。

後續還有更多功能:

index:create、update、delete

search:query(queryParser)、filter、sort、paging、highlight、facet

multiSearch

cache

 


 

keywords

1)elasticsearch java api VS rest api

2)elasticsearch nodeBuilder VS transportClient

 

補張ppt。

 


 

20140630 補充

TransportClient

The transport client allows to create a client that is not part of the cluster, but simply connects to one or more nodes directly by adding their respective addresses using addTransportAddress(org.elasticsearch.common.transport.TransportAddress).

addTransportAddress方法

Adds a transport address that will be used to connect to.The Node this transport address represents will be used if its possible to connect to it. If it is unavailable, it will be automatically connected to once it is up.In order to get the list of all the current connected nodes, please see connectedNodes().

從上文可知,能夠爲transportClient添加多個transportAddress,添加多個的目的是什麼呢?

當一個es服務(對應一個transportAddress)不可用時,client會自動發現當前可用的nodes(the current connected nodes),從如下這段代碼可知:

TransportClientNodesService

int index = randomNodeGenerator.incrementAndGet();
        if (index < 0) {
            index = 0;
            randomNodeGenerator.set(0);
        }
        RetryListener<Response> retryListener = new RetryListener<Response>(callback, listener, nodes, index);
        try {
            callback.doWithNode(nodes.get((index) % nodes.size()), retryListener);
        } catch (ElasticsearchException e) {
            if (e.unwrapCause() instanceof ConnectTransportException) {
                retryListener.onFailure(e);
            } else {
                throw e;
            }
        }

retryListener保證當前可用的nodes列表。

index是一個自增的int(針對同一個client),nodes.get((index) % nodes.size()能夠將請求均發到nodes上。注意這裏和索引的分片不是一回事。

理論上,Client能夠添加ES集羣中部分或所有nodes,而後輪詢「拿到」一個node,屆時client能夠和ES集羣進行通訊,並進行相應的操做。

至於具體的操做——

Index:分片(sharding,分片策略)->選定具體的node(Master)Index ->同步到對應的slave node

Search:從replSet中選定node(負載策略)->請求分發 ->結果集合並

等,後面再分析。

相關文章
相關標籤/搜索