Elasticsearch学习笔记系列3——REST API

从Elasticsearch 5.0开始引入了REST Client,使用HTTP的协议操作ES服务器。ES原生的Transport Client将在8.0后彻底取消,因此官方推荐使用REST API. 这是因为REST Client的初始化构建的线程的安全的,与应用的生命周期相同,但是使用完客户端后要关闭客户端来释放资源。

Elasticsearch Java REST API分为低级(low-level)和高级(high-level)两个接口,其中:

  • Java Low Level REST Client 允许用HTTP协议与ES集群通信,是面向用户的。
  • Java high Level REST Client 基于低级客户端,面向开发者,开发者可以用管饭提供的各种API实现自己的功能

这部分介绍低级客户端

五、Java Low Level REST API

低级客户端的特效包括:

  1. 最小化依赖
  2. 所有节点(nodes)的负载均衡
  3. 某个节点发生故障会自动转移到其他节点
  4. 对于失败的链接给予乘法,也就是失败次数越多,client下次尝试重新链接的时间就越长,
  5. 持续练级
  6. 跟踪(tracing)请求和相应的记录
  7. 可以自动发现集群中的节点(cluster nodes)

5.1 添加依赖

可以在maven的pom.xml中添加如下依赖

<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-client</artifactId>
    <version>6.3.2</version>
</dependency>

对于gradle工程,则添加:

dependencies {
    compile 'org.elasticsearch.client:elasticsearch-rest-client:6.3.2'
}

不同版本的ES选择对应的REST 客户端

5.2 初始化

使用ES 官方提供的REST接口时需要先初始化,使用ResClientBuilder类初始化,如下:

RestClient restClient = RestClient.builder(
        new HttpHost("localhost", 9200, "http"),
        new HttpHost("localhost", 9201, "http")).build();

调用完之后一定要关闭客户端

restClient.close();

5.3 请求

REST Client初始化后,可用同步方法performRequest()或者异步方法performRequestAsync()方法完成请求。

查看索引中节点的信息,可以直接用GET方法得到

Response response = restClient.performRequest("GET", "/"); 

查询某个属性和某个值为true的文档

Map<String, String> params = Collections.singletonMap("属性", "值");
Response response = restClient.performRequest("GET", "/", params); 

查看索引中”pretty“属性为true的文档,

Map<String, String> params = Collections.singletonMap("pretty", "true");
Response response = restClient.performRequest("GET", "/", params); 

此外,可以用Java中的HashMap自定义JSON请求

Map<String, String> params = Collections.emptyMap();
String jsonString = "JSON请求的字符串";
HttpEntity entity = new NStringEntity(jsonString, ContentType.APPLICATION_JSON);
Response response = restClient.performRequest("PUT", "索引/类型/id", params, entity);

如自定义一个类型为doc的文档,属于索引posts,文档id为1,该文档描述了用户名(user),提交时间(postDate)和信息(message)三个属性,用HashMap建立的JSON请求,并把该文档添加到索引中的代码为:

Map<String, String> params = Collections.emptyMap();
String jsonString = "{" +
            "\"user\":\"kimchy\"," +
            "\"postDate\":\"2013-01-30\"," +
            "\"message\":\"trying out Elasticsearch\"" +
        "}";
HttpEntity entity = new NStringEntity(jsonString, ContentType.APPLICATION_JSON);
Response response = restClient.performRequest("PUT", "/posts/doc/1", params, entity);

在比如,在自定义的spnews的索引中,查询关键字为周琦的有关文档

String key_word = "周琦";
String queryString = "{" +
"                   \"query\":{"+
"                   \"match\":{"+
"                     \"key_word\":\""+key_word+"\""+
"                   }" +
"                }"+
"               }";
HttpEntity entity = new NStringEntity(queryString,ContentType.APPLICATION_JSON);
String content = null;
try{
     Response response = restClient.performRequest("GET","/spnews/_search", params, entity);
     System.out.println(response.getStatusLines().getStatusCode());
     String responseBody = null;
     responseBody = EntityUtils.toString(response.getEntity());
}

此外还有异步请求,需要用listener监听。

六、Java High Level REST API

Java High Level Client 运行在Java Low Level REST 客户端上,面向开发人员,高级客户端提供API的具体方法,这些方法以请求对象(Request Object)为输入,返回响应对象(Response Object),每个API的方法都可以用同步或者异步的方式调用,异步方法返回的对象需要用监听器(listener)来接受。

Java High Level Client 依赖于ES核心工程(core project),因此与ES原生的Java API中的TransportClient有相同的输入和输出。

兼容性方法,High Level REST Client 与ES 版本号保持一致,并且可以在允许的最小版本(minor version)上运行。最推荐的还是让ES与REST Client的版本保持一致。

目前,Java REST Client API中已经实现了原生API中的大部分方法,开发者可以在官方的github issue上提交暂时还未实现的方法。当然这些方法都可以用JSON请求Low Level REST Client手动实现。

6.1 添加依赖

与Low Level REST Client一样,High Level REST Client也可以再maven中添加依赖实现:

<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>6.3.2</version>
</dependency>

gradle则是

dependencies {
    compile 'org.elasticsearch.client:elasticsearch-rest-high-level-client:6.3.2'
}

6.2 初始化

High-level REST 客户端使用RestHighLevelClient类来创建客户端

RestHighLevelClient client = new RestHighLevelClient(
        RestClient.builder(
                new HttpHost("localhost", 9200, "http"),
                new HttpHost("localhost", 9201, "http")));

使用完后,要关闭客户端

client.close();

6.3 对索引的操作

6.3.1 查看索引是否存在

使用GetIndexRequest来查看索引是否存在,如下

GetIndexRequest request = new GetIndexRequest();
request.indices("索引名"); 

对于建立的request对象,可是用一个bool变量来表示索引是否存在,6.3版本以前可以用:

boolean exists = client.indices().exists(request);

6.4版本开始使用

boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);

该请求也可以添加方法

request.local(false);                     //是否返回主节点信息
request.humanReadable(true);              //是否返回可读的信息
request.includeDefaults(false);           //是否返回每个结点的默认信息
request.indicesOptions(indicesOptions);   //控制结点的其他配置

6.3.2 删除索引

使用GetIndexRequest删除索引

DeleteIndexRequest request = new DeleteIndexRequest("索引名");

6.3版本前使用DeleteIndexResponse执行删除

DeleteIndexResponse deleteIndexResponse = client.indices().delete(request);

6.4版本后使用

DeleteIndexResponse deleteIndexResponse = client.indices().delete(request, RequestOptions.DEFAULT);

可以用一个boolean类型的变量判断是否删除成功

boolean acknowledged = deleteIndexResponse.isAcknowledged();

删除一个不存在的索引会抛出ElasticsearchException的异常,因此完整的删除操作为:

try {
    DeleteIndexRequest request = new DeleteIndexRequest("does_not_exist");
    client.indices().delete(request);
} catch (ElasticsearchException exception) {
    if (exception.status() == RestStatus.NOT_FOUND) {
        
    }
}

6.4版本以后则是:

try {
    DeleteIndexRequest request = new DeleteIndexRequest("does_not_exist");
    client.indices().delete(request, RequestOptions.DEFAULT);
} catch (ElasticsearchException exception) {
    if (exception.status() == RestStatus.NOT_FOUND) {
        
    }
}

6.3.3 创建索引

使用CreateIndexRequest创建请求类

CreateIndexRequest request = new CreateIndexRequest("索引名");

可以使用该类下的settings方法设置索引的一些属性,比如分片数,冗余数

request.settings(Settings.builder() 
    .put("index.number_of_shards", 3)
    .put("index.number_of_replicas", 2)
);

上边介绍说,所有ES的请求都是JSON,因此可以用各种创建JSON的方式设置索引的手机号码购买平台属性,比如用纯文本创建。使用到的JSON请求,类型为_doc,具体属性为:

{
  "_doc": 
  {
   "properties": 
      { 
        "message": 
          {
            "type": "text"
          }
      }
   }
}  

纯文本构建的JSON请求设置索引的属性的代码为:

request.mapping("_doc", 
        "{\n" +
        "  \"_doc\": {\n" +
        "    \"properties\": {\n" +
        "      \"message\": {\n" +
        "        \"type\": \"text\"\n" +
        "      }\n" +
        "    }\n" +
        "  }\n" +
        "}", 
        XContentType.JSON);

比如用HashMap构建JSON请求:

Map<String, Object> jsonMap = new HashMap<>();
Map<String, Object> message = new HashMap<>();
message.put("属性1", "值1");
Map<String, Object> properties = new HashMap<>();
properties.put("属性2", message);
Map<String, Object> mapping = new HashMap<>();
mapping.put("属性3", properties);
jsonMap.put("类型名", mapping);
request.mapping("类型名", jsonMap); 

上述例子就可以写成:

Map<String, Object> jsonMap = new HashMap<>();
Map<String, Object> message = new HashMap<>();
message.put("type", "text");
Map<String, Object> properties = new HashMap<>();
properties.put("message", message);
Map<String, Object> mapping = new HashMap<>();
mapping.put("properties", properties);
jsonMap.put("_doc", mapping);
request.mapping("_doc", jsonMap); 

还可以使用ES内建的JSON helper生成JSON格式的请求,上边的例子可以写成

XContentBuilder builder = XContentFactory.jsonBuilder();
builder.startObject();
{
    builder.startObject("_doc");
    {
        builder.startObject("properties");
        {
            builder.startObject("message");
            {
                builder.field("type", "text");
            }
            builder.endObject();
        }
        builder.endObject();
    }
    builder.endObject();
}
builder.endObject();
request.mapping("_doc", builder); 

还可以用键-值组合自动生成JSON格式的设置项

request.mapping("_doc", "message", "type=text");

对于创建好的索引,还可以起个别名

request.alias(new Alias("twitter_alias").filter(QueryBuilders.termQuery("user", "kimchy"))); 

也可直接使用未加任何处理的字符串构建JSON请求,并设置各种属性来创建索引

request.source("{\n" +
        "    \"settings\" : {\n" +
        "        \"number_of_shards\" : 1,\n" +
        "        \"number_of_replicas\" : 0\n" +
        "    },\n" +
        "    \"mappings\" : {\n" +
        "        \"_doc\" : {\n" +
        "            \"properties\" : {\n" +
        "                \"message\" : { \"type\" : \"text\" }\n" +
        "            }\n" +
        "        }\n" +
        "    },\n" +
        "    \"aliases\" : {\n" +
        "        \"twitter_alias\" : {}\n" +
        "    }\n" +
        "}", XContentType.JSON); 

对于创建索引的请求,可是用CreateIndexRequest执行创建

CreateIndexResponse createIndexResponse = client.indices().create(request);

6.4版本以上使用

CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT);

用以下语句表示创建成功

boolean acknowledged = createIndexResponse.isAcknowledged(); 
boolean shardsAcknowledged = createIndexResponse.isShardsAcknowledged(); 

创建完的索引还需要设置映射,映射就相当于数据库中的字段,映射同样用JSON请求实现,如下

XContentBuilder mapjasonbuilder = mappingIndexJSON()
request.mapping("类型名",mapjasonbuilder)

其中mappingIndexJSON()是用XContentBuilder来创建JSON请求,与上边的创建设置项的JSON类似

6.4 对文档的操作

补充中...

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值