赞
踩
使用java操作es集群很简单,只需要在pom文件里引入es客户端的依赖即可,如下:
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>6.6.1</version>
</dependency>
下面记录一下几个基本的api操作:
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的记录。
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(); } }
下面演示的是一个通过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();
}
这个代码在上面有提到,通过调用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(); } }
如下:索引中有对应的字段就更新,没有就添加
/** * 从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(); }
注意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();
}
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(); }
/** * 批量查询 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(); }
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,这里不一一记录,有兴趣的同学可自行前往官网查看
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。