https://blog.csdn.net/wanbf123/article/details/78088444node
ES提供了多種語言(包括Java、Python、PHP、Ruby等)版本的Client API,能夠使用這些Client API編程實現數據操做功能。apache
使用Java API須要依賴ES所提供的jar包,咱們使用maven來下載所需的依賴包,maven依賴定義以下:編程
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>1.5.0</version>
</dependency>jsonversion表示依賴包的版本,能夠輸入任意存在的版本,本文的示例中使用1.5.0版的API。注意,建議API的版本與ES集羣所使用的版本保持一致,以避免出現因版本不一致而致使的衝突。app
ES中全部的Java API調用都要使用Client對象,ES爲API調用者提供了兩類Client對象:NodeClient和TransportClient。下面來說講這兩類Client的差別和使用場景。elasticsearch
NodeClient是一種嵌入式節點客戶端。它首先在客戶端啓動一個節點(Node),並加入同名集羣內。這個節點能夠保存數據,而且數據可以被索引。而後從這個節點中獲取Client,這類Client就是NodeClient。NodeClient無需指明ES服務端的地址,操做的數據位於啓動的節點所在的集羣中。maven
得到NodeClient的代碼以下所示:工具
import org.elasticsearch.client.Client;
import org.elasticsearch.client.node.NodeClient;
import org.elasticsearch.node.Node;
import static org.elasticsearch.node.NodeBuilder.nodeBuilder;
public class MyNodeClient {
public static void main(String[] args) {
// 啓動一個本地節點,並加入子網內的ES集羣
Node node = nodeBuilder()
.clusterName("elasticsearch") // 要加入的集羣名爲elasticsearch
// .client(true) //若是設置爲true,則該節點不會保存數據
.data(true) // 本嵌入式節點能夠保存數據
.node(); // 構建並啓動本節點
// 得到一個Client對象,該對象能夠對子網內的「elasticsearch」集羣進行相關操做。
Client nodeClient = node.client();
}
}測試
運行這段代碼以後,能夠看到工程中新增了一個data文件夾,這是由於data(true)
將Node設置爲能夠存放數據的節點,數據正是放在了data文件夾下。ui
NodeClient適合用做單元或集成測試,而不適合用於生產環境。
TransportClient鏈接遠端的ES集羣,其自己並不會加入集羣。
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.transport.TransportAddress;
import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder;
public class MyTransportClient {
public static void main(String[] args) {
// 配置信息
Settings esSetting = settingsBuilder()
.put("cluster.name", "elasticsearch")
.build();
TransportClient transportClient = new TransportClient(esSetting);
// 添加鏈接地址
TransportAddress address = new InetSocketTransportAddress("192.168.1.110", 9300);
TransportAddress address2 = new InetSocketTransportAddress("192.168.1.111", 9300);
transportClient.addTransportAddress(address);
transportClient.addTransportAddress(address2);
}
}
TransportClient適合用於生產環境中。
下面的方法建立一個索引,並同時建立一個mapping。mapping能夠傳入符合格式要求的json字符串。通常狀況下,咱們能夠使用下面的方式來生成所需的json字符串。
/**
* 建立一個索引
* @param indexName 索引名
*/
public void createIndex(String indexName) {
try {
CreateIndexResponse indexResponse = this.client
.admin()
.indices()
.prepareCreate(indexName)
.get();
System.out.println(indexResponse.isAcknowledged()); // true表示建立成功
} catch (ElasticsearchException e) {
e.printStackTrace();
}
}
若是須要在索引上新建mapping,可經過下面的代碼來實現。
/**
* 給索引增長mapping。
* @param index 索引名
* @param type mapping所對應的type
*/
public void addMapping(String index, String type) {
try {
// 使用XContentBuilder建立Mapping
XContentBuilder builder =
XContentFactory.jsonBuilder()
.startObject()
.field("properties")
.startObject()
.field("name")
.startObject()
.field("index", "not_analyzed")
.field("type", "string")
.endObject()
.field("age")
.startObject()
.field("index", "not_analyzed")
.field("type", "integer")
.endObject()
.endObject()
.endObject();
System.out.println(builder.string());
PutMappingRequest mappingRequest = Requests.putMappingRequest(index).source(builder).type(type);
this.client.admin().indices().putMapping(mappingRequest).actionGet();
} catch (ElasticsearchException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 刪除索引
* @param index 要刪除的索引名
*/
public void deleteIndex(String index) {
DeleteIndexResponse deleteIndexResponse =
this.client
.admin()
.indices()
.prepareDelete(index)
.get();
System.out.println(deleteIndexResponse.isAcknowledged()); // true表示成功
}
增刪改查是數據的基本操做,同時也是使用頻率最高的一類操做。本小節介紹使用Java API來實現document的增刪改查。
/**
* 建立一個文檔
* @param index index
* @param type type
*/
public void createDoc(String index, String type) {
try {
// 使用XContentBuilder建立一個doc source
XContentBuilder builder =
XContentFactory.jsonBuilder()
.startObject()
.field("name", "zhangsan")
.field("age", "lisi")
.endObject();
IndexResponse indexResponse = this.client
.prepareIndex()
.setIndex(index)
.setType(type)
// .setId(id) // 若是沒有設置id,則ES會自動生成一個id
.setSource(builder.string())
.get();
System.out.println(indexResponse.isCreated());
} catch (ElasticsearchException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 更新文檔
* @param index
* @param type
* @param id
*/
public void updateDoc(String index, String type, String id) {
try {
XContentBuilder builder =
XContentFactory.jsonBuilder()
.startObject()
.field("name", "lisi")
.field("age", 12)
.endObject();
UpdateResponse updateResponse =
this.client
.prepareUpdate()
.setIndex(index)
.setType(type)
.setId(id)
.setDoc(builder.string())
.get();
System.out.println(updateResponse.isCreated()); // true表示成功
} catch (ElasticsearchException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}【注意】id參數必須是肯定存在的id值,不然會拋出document missing的異常。
查詢文檔能夠是根據id查詢,也能夠是根據複雜的查詢條件查詢。根據id的get查詢代碼以下。
/**
* 根據ID查詢一條數據記錄。
* @param id 要查詢數據的ID。
* @return 返回查詢出來的記錄對象的json字符串。
*/
public String get(String index, String type, String id) {
GetResponse getResponse = this.client
.prepareGet() // 準備進行get操做,此時還有真正地執行get操做。(與直接get的區別)
.setIndex(index) // 要查詢的
.setType(type)
.setId(id)
.get();
return getResponse.getSourceAsString();
}
基於複雜查詢條件的示例代碼以下。
/**
* 使用filter方式查詢數據。
* @param index 數據所在的索引名
* @param type 數據所在的type
* @return
*/
public List<String> queryByFilter(String index, String type) {
// 查詢名爲zhangsan的數據
FilterBuilder filterBuilder = FilterBuilders.termFilter("name", "zhangsan");
SearchResponse searchResponse =
this.client
.prepareSearch()
.setIndices(index)
.setTypes(type)
.setPostFilter(filterBuilder)
.get();
List<String> docList = new ArrayList<String>();
SearchHits searchHits = searchResponse.getHits();
for (SearchHit hit : searchHits) {
docList.add(hit.getSourceAsString());
}
return docList;
}
下面的代碼刪除指定id的文檔。
/**
* 刪除一條數據
* @param index
* @param type
* @param id
*/
public void deleteDoc(String index, String type, String id) {
DeleteResponse deleteResponse = this.client
.prepareDelete()
.setIndex(index)
.setType(type)
.setId(id)
.get();
System.out.println(deleteResponse.isFound()); // true表示成功
}
根據複雜的查詢條件來刪除文檔。
/**
* 根據查詢條件刪除文檔。
*/
public void deleteByQuery(String index, String type) {
try {
QueryBuilder queryBuilder = QueryBuilders.termQuery("name", "zhangsan");
DeleteByQueryResponse deleteByQueryResponse = this.client
.prepareDeleteByQuery(index)
.setTypes(type)
.setQuery(queryBuilder)
.get();
} catch (ElasticsearchException e) {
e.printStackTrace();
}
}
聚合操做的API稍微比較複雜一點,本文僅以min聚合的示例來講明聚合API的調用方式,其餘的聚合API調用步驟相似。
/** * 使用min聚合查詢某個字段上最小的值。 * @param index * @param type */ public void min(String index, String type) { SearchResponse response = this.client .prepareSearch(index) .addAggregation(AggregationBuilders.min("min").field("age")) .get(); InternalMin min = response.getAggregations().get("min"); System.out.println(min.getValue()); }