使用java操作es集群很简单,只需要在pom文件里引入es客户端的依赖即可,如下:
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>6.6.1</version>
</dependency>
下面记录一下几个基本的api操作:
1.使用java连接ES集群
es官方从6.0开始推荐大家使用高级客户端连接es集群,并在7.0以后摒弃了低级客户端通信。所以这里用高级客户端RestHighLevelClient作为案例,注意客户端的版本号要与集群主版本号保持一致,我的es版本号是6.6.1,所以这里客户端版本号也采用6.6.1,代码如下:
public class ElasticSearchClient {
/**
* 使用RestHighLevelClient连接elasticsearch集群测试
* @throws IOException
*/
@Test
public void test1() throws IOException {
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("192.168.137.228",9200,"http")));
GetRequest getRequest = new GetRequest("test","user","1");
getRequest.fetchSourceContext(new FetchSourceContext(false));
getRequest.storedFields("_none_");
boolean exist = client.exists(getRequest, RequestOptions.DEFAULT);
if(exist){
System.out.println("文档存在");
}else {
System.out.println("文档不存在");
}
client.close();
}
}
以上代码示例了一个连接es集群,并从es集群获取索引为test,类型为user,id为1的记录。
2.ES documentAPI-索引index
es官方提供了非常丰富的api来对es集群做一系列的操作,具体详细的说明,有兴趣的同学可以去es官网查看api详解,这里只做demo演示。
/**
* elasticsearch连接集群创建索引的四种方法
*/
public class ElasticSearchDocumentAPI {
public RestHighLevelClient restHighLevelClient;
@BeforeEach
public void connectES(){
restHighLevelClient = new RestHighLevelClient(RestClient.builder(new HttpHost("192.168.137.228",9200,"http")));
}
/**
* es创建索引API,方法一,使用json串
*/
@Test
public void testIndex() throws IOException {
String jsonString ="{"+
" \"user\" : \"kimchy\",\n" +
" \"post_date\" : \"2009-11-15T14:12:12\",\n" +
" \"message\" : \"trying out Elasticsearch\"\n" +
"}";
IndexRequest request = new IndexRequest("posts","doc","2");
request.source(jsonString,XContentType.JSON);
IndexResponse response = restHighLevelClient.index(request,RequestOptions.DEFAULT );
System.out.println(response.getId());
restHighLevelClient.close();
}
/**
* es创建索引API,方法二,MAP
*/
@Test
public void testIndex2() throws IOException {
Map<String,Object> jsonMap = new HashMap<String, Object>();
jsonMap.put("user", "kimchy");
jsonMap.put("post_date", "2009-11-15T14:12:12");
jsonMap.put("message", "trying out Elasticsearch");
IndexRequest request = new IndexRequest("posts","doc","3");
request.source(jsonMap);
IndexResponse response = restHighLevelClient.index(request,RequestOptions.DEFAULT );
System.out.println(response.getId());
restHighLevelClient.close();
}
/**
* es创建索引API,方法三,XContentBuilder
*/
@Test
public void testIndex3() throws IOException {
XContentBuilder builder = XContentFactory.jsonBuilder();
builder.startObject();
{
builder.field("user","kimchy");
builder.field("post_date",new Date());
builder.field("message","trying out Elasticsearch");
}
builder.endObject();
IndexRequest request = new IndexRequest("posts","doc","4");
request.source(builder);
IndexResponse response = restHighLevelClient.index(request,RequestOptions.DEFAULT );
System.out.println(response.getId());
restHighLevelClient.close();
}
/**
* es创建索引API,方法四,Object
*/
@Test
public void testIndex4() throws IOException {
IndexRequest request = new IndexRequest("posts","doc","5")
.source("user","kimchy",
"post_date",new Date(),
"message","trying out Elasticsearch");
IndexResponse response = restHighLevelClient.index(request,RequestOptions.DEFAULT );
System.out.println(response.getId());
restHighLevelClient.close();
}
}
3.索引查询
下面演示的是一个通过api查询索引的demo
/**
* 从es查询索引get
* @throws IOException
*/
@Test
public void testGet() throws IOException {
RestHighLevelClient restHighLevelClient= new RestHighLevelClient(RestClient.builder(new HttpHost("192.168.137.228",9200,"http")));
GetRequest request = new GetRequest("posts","doc","5");
GetResponse response = restHighLevelClient.get(request,RequestOptions.DEFAULT );
System.out.println(response.getSource());
restHighLevelClient.close();
}
4.判断索引是否存在
这个代码在上面有提到,通过调用exists来实现
public class ElasticSearchClient {
/**
* 使用RestHighLevelClient连接elasticsearch集群测试
* @throws IOException
*/
@Test
public void test1() throws IOException {
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("192.168.137.228",9200,"http")));
GetRequest getRequest = new GetRequest("test","user","1");
getRequest.fetchSourceContext(new FetchSourceContext(false));
getRequest.storedFields("_none_");
boolean exist = client.exists(getRequest, RequestOptions.DEFAULT);
if(exist){
System.out.println("文档存在");
}else {
System.out.println("文档不存在");
}
client.close();
}
}
5.索引更新
如下:索引中有对应的字段就更新,没有就添加
/**
* 从es更新索引update
* @throws IOException
*/
@Test
public void testUpdate() throws IOException {
RestHighLevelClient restHighLevelClient= new RestHighLevelClient(RestClient.builder(new HttpHost("192.168.137.228",9200,"http")));
UpdateRequest request = new UpdateRequest("posts","doc","1");
String jsonString ="{"+
" \"updated\" : \"2019-07-27\",\n" +
" \"reason\" : \"daily update\"\n" +
"}";
request.doc(jsonString,XContentType.JSON);
UpdateResponse response = restHighLevelClient.update(request,RequestOptions.DEFAULT );
System.out.println(response.getGetResult());
restHighLevelClient.close();
}
6.索引删除
注意es的删除操作是标记删除,并不会马上生效,它会在你之后添加更多索引的时候进行清理,代码如下:
/**
* 从es删除索引delete
* @throws IOException
*/
@Test
public void testDelete() throws IOException {
RestHighLevelClient restHighLevelClient= new RestHighLevelClient(RestClient.builder(new HttpHost("192.168.137.228",9200,"http")));
DeleteRequest request = new DeleteRequest("posts","doc","5");
DeleteResponse response = restHighLevelClient.delete(request,RequestOptions.DEFAULT );
restHighLevelClient.close();
}
7.ES批量操作bulk
es提供了buik对应api来执行java客户端批量新增、更改、删除,如下:
/**
* 批量操作bulk
* @throws IOException
*/
@Test
public void testBulk() throws IOException {
RestHighLevelClient restHighLevelClient= new RestHighLevelClient(RestClient.builder(new HttpHost("192.168.137.228",9200,"http")));
BulkRequest request = new BulkRequest();
request.add(new IndexRequest("posts","doc","5").source("field","foo"));
request.add(new IndexRequest("posts","doc","4").source("field","bar"));
request.add(new IndexRequest("posts","doc","3").source("field","baz"));
BulkResponse response = restHighLevelClient.bulk(request,RequestOptions.DEFAULT );
if(response.hasFailures()){ //如果有失败的请求,遍历打印请求信息
for (BulkItemResponse bulkItemResponse:response){
BulkItemResponse.Failure failure = bulkItemResponse.getFailure();
System.out.println(failure.getMessage());
}
}
restHighLevelClient.close();
}
8.批量查询索引mget
/**
* 批量查询 mget
* @throws IOException
*/
@Test
public void testMget() throws IOException {
RestHighLevelClient restHighLevelClient= new RestHighLevelClient(RestClient.builder(new HttpHost("192.168.137.228",9200,"http")));
MultiGetRequest request = new MultiGetRequest();
request.add(new MultiGetRequest.Item("test","user","1"));
request.add(new MultiGetRequest.Item("test","user","2"));
MultiGetResponse responses = restHighLevelClient.mget(request, RequestOptions.DEFAULT);
//遍历得到的结果,并输出
for(MultiGetItemResponse itemResponse:responses){
GetResponse response = itemResponse.getResponse();
if(response.isExists()){
System.out.println(response.getSourceAsString());
}
}
restHighLevelClient.close();
}
9.SearchType
es把数据存在了多个分片中,查询的时候会把请求分发到这多个分片中,各个分片都会返回查询结果,最后对这些结果做聚合。由此衍生出了几种查询类型:
Search and fetch:向所有分片发送查询请求,所有分片将查询结果返回后聚合。查询速率快,但是结果数据量可能比预期大很多
Search then fetch:向所有分片发送查询请求,各分片只返回文档id和排名相关信息,聚合后进行一个总得排名,最后取前n个,根据文档id再去对应的分片查询文档内容,这样的好处是得到的数据量是和预期一样的,但因为各个分片的打分标准不一样,可能导致得到的数据不准确
DFS Search and fetch:它的排序方法和第一种方法大致一样,只不过它在查询前,先给所有分片发请求,将所有分片文档的频率和词频汇总到一起,统一各个分片的打分标准,在进行后面的排序。这么做返回的结果准确,但是返回的数据量可能比预期大很多
DFS Search then fetch:它的排序方法和第二种方法大致一样,但也是在查询前对各分片打分标准做了统一,他的优点是返回的数据量和数据都是准确的,但是查询效率最低,但在可容忍范围内。
用户可以根据实际需求对排序标准做选择
/**
*SearchType
*/
@Test
public void testSearchType() throws IOException {
RestHighLevelClient restHighLevelClient= new RestHighLevelClient(RestClient.builder(new HttpHost("192.168.137.228",9200,"http")));
SearchRequest searchRequest = new SearchRequest();
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.termQuery("age", 28));
searchRequest.source(searchSourceBuilder); //设置获取数据内容
searchRequest.indices("test"); //设置索引
searchRequest.types("user"); //设置类型
searchRequest.searchType(SearchType.QUERY_THEN_FETCH); //设置searchType
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
SearchHits hits = searchResponse.getHits();
System.out.println(hits.getTotalHits());
restHighLevelClient.close();
}
ES客户端还提供了其他许多的api,这里不一一记录,有兴趣的同学可自行前往官网查看