前一篇有关ES的文章介绍了使用Rest方式调用ES的聚合API。Rest API使用了HTTP协议,按理来说,可以直接使用类似HttpClient的工具直接调用Rest API。虽然笔者并没有尝试过,但稍微想想一下就知道这种方法是可行的。这种方法主要有下面几个弊端:

  1. 需要开启ES的Http服务和端口。ES提供的Http服务功能非常全面,没有提供权限控制,防护也比较脆弱。一旦遭到破解,则数据面临极大的风险。所以,建议在生产中关闭Http服务,或者自己增加一层代理来实现权限控制。
  2. 调用比较困难。Rest API的核心是url和post数据,url直接需传入字符串,这样就不能使用IDE的查错功能。需要记忆的东西太多,不确定时就要去查API,影响开发效率。
  3. Http协议的一大特点是无连接性。也就是每一次请求都需要建立新的连接,我们知道tcp连接是比较耗时的过程。从性能的角度来说,直接使用Rest API也是不合适的。

ES所提供的Http服务适合用作集群状态和数据的监控,而不适合直接用于数据操作。ES提供了多种语言(包括Java、Python、PHP、Ruby等)版本的Client API,可以使用这些Client API编程实现数据操作功能。作为一个Java语言编程者,本文主要介绍使用Java版本的Client来操作数据。使用Java API需要依赖ES所提供的jar包,我们使用maven来下载所需的依赖包,maven依赖定义如下:

<dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>1.5.0</version>
</dependency>

version表示依赖包的版本,可以输入任意存在的版本,本文的示例中使用1.5.0版的API。注意,建议API的版本与ES集群所使用的版本保持一致,以免出现因版本不一致而导致的冲突。

本文的主要内容包括:

  1. 介绍两类Client,解释它们的之间的差异;
  2. 使用Client进行index、document和聚合相关的操作。

1. Client

ES中所有的Java API调用都要使用Client对象,ES为API调用者提供了两类Client对象:NodeClient和TransportClient。下面来讲讲这两类Client的差异和使用场景。

1.1 NodeClient

NodeClient是一种嵌入式节点客户端。它首先在客户端启动一个节点(Node),并加入同名集群内。这个节点可以保存数据,并且数据能够被索引。然后从这个节点中获取Client,这类Client就是NodeClient。NodeClient无需指明ES服务端的地址,操作的数据位于启动的节点所在的集群中。下面是获得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文件夹下。

NodeClient适合用作单元或集成测试,而不适合用于生产环境。

1.2 TransportClient

TransportClient连接远端的ES集群,其本身并不会加入集群。创建TransportClient的代码如下:

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适合用于生产环境中。

2. Index操作

本小节介绍如果使用Java API创建和删除索引。

2.1 创建索引

废话先不说,上代码先。下面的方法创建一个索引,并同时创建一个mapping。mapping可以传入符合格式要求的json字符串。一般情况下,我们可以使用下面的方式来生成所需的json字符串。

  1. 手动拼接json字符串
  2. 使用类似jackson的工具将对象转换为相应的json字符串
  3. 使用ES内置的XContentFactory.jsonBuilder()来创建json字符串。

本文的示例中均使用ES自带的XContentFactory.jsonBuilder()来构建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创建MappingXContentBuilder 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();}
}

3.1 删除索引

/*** 删除索引* @param index 要删除的索引名*/
public void deleteIndex(String index) {DeleteIndexResponse deleteIndexResponse = this.client.admin().indices().prepareDelete(index).get();System.out.println(deleteIndexResponse.isAcknowledged()); // true表示成功
}

3. 文档CURD操作

增删改查是数据的基本操作,同时也是使用频率最高的一类操作。本小节介绍使用Java API来实现document的增删改查。

3.1 新增文档

/*** 创建一个文档* @param index index* @param type type*/
public void createDoc(String index, String type) {try {// 使用XContentBuilder创建一个doc sourceXContentBuilder 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();}
}

3.2 更新文档

/*** 更新文档* @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的异常。

3.3 查询文档

查询文档可以是根据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();
}
````基于复杂查询条件的示例代码如下。<div class="se-preview-section-delimiter"></div>```java
/*** 使用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;
}

3.4 删除文档

下面的代码删除指定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();}
}

4. 聚合操作

聚合操作的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());
}

源代码地址:https://github.com/xialei199023/blog-demo

实时搜索引擎Elasticsearch(5)——Java API的使用相关推荐

  1. ElasticSearch 使用Java Api访问集群

    ElasticSearch 使用Java Api访问集群 1.创建maven工程导入pom依赖 <dependencies><dependency><groupId> ...

  2. 实时搜索引擎Elasticsearch(4)——Aggregations (聚合)API的使用

    上一篇博客介绍了ES中的简单查询API的使用,本篇将介绍ES提供的聚合API的使用.ES提供的聚合功能可以用来进行简单的数据分析.本文仍然以上一篇提供的数据为例来讲解.数据如下: studentNo ...

  3. java search 不能使用方法_ElasticSearch实战系列三: ElasticSearch的JAVA API使用教程

    前言 在上一篇中介绍了ElasticSearch实战系列二: ElasticSearch的DSL语句使用教程---图文详解,本篇文章就来讲解下 ElasticSearch 6.x官方Java API的 ...

  4. Es elasticsearch 十七 Java api 实现聚合 几个聚合示例 sql 开启许可 新特效 java 实现es7 sql 功能

    目录 Java api 实现聚合 依赖 简单聚合按照颜色分组获取每个卖出数量 聚合每个颜色卖出数量,及平均价格(每个分桶子聚合) 按照颜色分组 ,获取销售数量,avg min max sum 按照60 ...

  5. Elasticsearch——使用Java API实现ES中的索引、映射、文档操作

    文章目录: 1.开篇 2.案例详解 2.1 创建ES客户端:完成与ES服务端的连接 2.2 创建索引 2.3 查看索引 2.4 删除索引 2.5 创建文档 2.6 修改文档 2.7 查看文档 2.8 ...

  6. 实时搜索引擎Elasticsearch——Rest API的使用

    ES为开发者提供了非常丰富的基于HTTP协议的Rest API,只需要向ES服务端发送简单的Rest请求,就可以实现非常强大的功能.本篇文章主要介绍ES中常用操作的Rest API的使用,同时会讲解E ...

  7. 实时搜索引擎Elasticsearch(2)——Rest API的使用

    上一篇文章简单的介绍了ES的基本概念.安装运行等内容,本文将介绍ES中的常用Rest API. ES为开发者提供了非常丰富的基于HTTP协议的Rest API,只需要向ES服务端发送简单的Rest请求 ...

  8. 实时搜索引擎Elasticsearch(3)——查询API的使用

    上一篇文章介绍了ES中的Rest API,本章将重点介绍ES中的查询API的使用.由于笔者在实际项目仅仅将ES用作索引数据库,并没有深入研究过ES的搜索功能.而且鉴于笔者的搜索引擎知识有限,本文将仅仅 ...

  9. ElasticSearch之Java Api 测试

    增加Maven依赖 <dependency><groupId>org.elasticsearch</groupId><artifactId>elasti ...

最新文章

  1. 收缩临时库 shrink tempdb
  2. dwarf tower
  3. python多线程网络编程_python之网络编程-多线程
  4. CodeForces - 1293C NEKO's Maze Game(思维,水题)
  5. Mysql存储过程(四)——异常处理
  6. leetcode90. 子集 II
  7. 记录Yii2代码调试中出现的两个问题(截图展示)
  8. 项目构建之maven篇:3.m2eclipse使用
  9. vue nextTick深入理解-vue性能优化、DOM更新时机、事件循环机制
  10. Windows Server 2008 R2 远程桌面服务RDS和VDI介绍
  11. c语言课程设计错误总结,C语言课程设计总结总结经验
  12. 利用EDA365 SKILLS 生成gerber和手动生成
  13. 第4章 程序的控制结构(单元测试题Python含答案)
  14. 关于sourcetree这是一个无效源路径的解决办法
  15. android 微信架构,微信App支付技术架构全解析
  16. jQuery读取Table表格数据
  17. 释放自我。回归本性。要成功。
  18. 关于SQL Server numeric数据类型介绍
  19. ARM平台处理器简介-ARMv7
  20. 5年专业研究,这份云原生安全指南请查收

热门文章

  1. 动态毕业设计答辩PPT模板
  2. AI换声,只需5秒音源,这个网络就能实时“克隆”你的声音
  3. 一个Web服务的性能瓶颈分析及对策
  4. 计算机音乐先点什么,我电脑上有几千首歌,想在歌曲前面加上序号,但我忘了怎样使用拖把更? 爱问知识人...
  5. 《花雕学AI》ChatGPT 的 Prompt 用法,不是随便写就行的,这 13 种才是最有效的
  6. 【动手学习pytorch笔记】24.门控循环单元GRU
  7. 字符串 汉字转拼音 pinyin4j
  8. 由浅入深的了解高速数据采集卡
  9. 江苏实现自然村通宽带 农村宽带网速可达4M
  10. 树莓派基于c语言开发板,在树莓派等基于ARM的开发板运行.NET Core程序