Elasticsearch Java Client入门

序言

Elasticsearch(名称太长,后面简称ES)作为一个搜索引擎,目前可谓是如日中天,几乎和solr齐驾并驱。关于他能做什么,跟云计算有什么关系,在此不再描述。但是ES的官方文档,特别是关于java的客户端文档,真是少的可怜,甚至连个完整的增删改的示例都没有。在此,我就献丑了。
在开始讲解之前,还是先做个铺垫,为了能够有一个可以索引的模型,我们自定义了一个模型,暂时起个名称叫LogModel吧,这个模型有各种数据类型,int,long,String,list,但千万不要认为这是跟记录日志有关的一个模型。作为索引的一个最简单模型。代码如下:

1import java.util.ArrayList; 2import java.util.List; 3import java.util.Random; 4import java.util.UUID; 5/** * 瞎编的一个模型,跟日志基本没有关系 * @author donlian */ 6public class LogModel { 7 //主ID 8 private long id; 9 //次ID 10 private int subId; 11 /** * 系统名称 */ 12 private String systemName; 13 private String host; 14 15 //日志描述 16 private String desc; 17 private List<Integer> catIds; 18 public LogModel(){ 19 Random random = new Random(); 20 this.id = Math.abs(random.nextLong()); 21 int subId = Math.abs(random.nextInt()); 22 this.subId = subId; 23 List<Integer> list = new ArrayList<Integer>(5); 24 for(int i=0;i<5;i++){ 25 list.add(Math.abs(random.nextInt())); 26 } 27 this.catIds = list; 28 this.systemName = subId%1 == 0?"oa":"cms"; 29 this.host = subId%1 == 0?"10.0.0.1":"10.2.0.1"; 30 this.desc = "中文" + UUID.randomUUID().toString(); 31 } 32 public LogModel(long id,int subId,String sysName,String host,String desc,List<Integer> catIds){ 33 this.id = id; 34 this.subId = subId; 35 this.systemName = sysName; 36 this.host = host; 37 this.desc = desc; 38 this.catIds = catIds; 39 } 40...//省去get,set方法 41}

同时,因为ES在索引的时候,一般都用json格式,因此,使用jackson定义了一个将对象转化成json的工具类,也很简单,代码:

1public class ESUtils { 2 private static ObjectMapper objectMapper = new ObjectMapper(); 3 public static String toJson(Object o){ 4 try { 5 return objectMapper.writeValueAsString(o); 6 } catch (JsonProcessingException e) { 7 e.printStackTrace(); 8 } 9 return ""; 10 } 11}

在开始进行操作ES服务器之前,我们必须得获得ES的API,简单介绍一下ES操作服务器的两种方式,一种是使用Node方式,即本机也启动一个ES,然后跟服务器的ES进行通信,这个node甚至还能存储(奇怪,一般需要这样的方式吗?),另一种,就是下面我介绍的这一种,通过一个对象使用http协议跟服务器进行交互。
获得一个ES客户端API的代码如下:

1Settings settings = ImmutableSettings.settingsBuilder() 2 //指定集群名称 3 .put("cluster.name", "elasticsearch") 4 //探测集群中机器状态 5 .put("client.transport.sniff", true).build(); 6 /* * 创建客户端,所有的操作都由客户端开始,这个就好像是JDBC的Connection对象 * 用完记得要关闭 * 注意client里面包含了连接池,对于client而言用完之后需要关闭,但是针对连接而言不需要关闭 */ 7 Client client = new TransportClient(settings) 8 .addTransportAddress(new InetSocketTransportAddress("192.168.1.106", 9300));

Client对象,可以理解为数据库的Connection对象。好了,准备工作完成,下面就开始增删改查。
Client更类似与连接池

Index(增加)

ES里面的增加对象不叫什么add,save等,叫index。但无论叫什么名称,反正就是向ES服务器里面加数据。上面说过一个对象转json的工具类,其实ES的API中,是自带构建json的工具类的。

1import org.elasticsearch.action.index.IndexResponse; 2import org.elasticsearch.client.Client; 3import org.elasticsearch.client.transport.TransportClient; 4import org.elasticsearch.common.settings.ImmutableSettings; 5import org.elasticsearch.common.settings.Settings; 6import org.elasticsearch.common.transport.InetSocketTransportAddress; 7 8import com.donlianli.es.ESUtils; 9import com.donlianli.es.model.LogModel; 10/** * 向ES添加索引对象 * @author donlian */ 11public class IndexTest { 12 public static void main(String[] argv){ 13 Settings settings = ImmutableSettings.settingsBuilder() 14 //指定集群名称 15 .put("cluster.name", "elasticsearch") 16 //探测集群中机器状态 17 .put("client.transport.sniff", true).build(); 18 /* * 创建客户端,所有的操作都由客户端开始,这个就好像是JDBC的Connection对象 * 用完记得要关闭 */ 19 Client client = new TransportClient(settings) 20 .addTransportAddress(new InetSocketTransportAddress("192.168.1.106", 9300)); 21 String json = ESUtils.toJson(new LogModel()); 22 //在这里创建我们要索引的对象 23 IndexResponse response = client.prepareIndex("twitter", "tweet") 24 //必须为对象单独指定ID 25 .setId("1") 26 .setSource(json) 27 .execute() 28 .actionGet(); 29 //多次index这个版本号会变 30 System.out.println("response.version():"+response.version()); 31 client.close(); 32 } 33}

运行这个代码,就向ES插入了一条数据,你运行两遍,还是一条。ES根据你设置的ID来设置对象,如果没有则插入,有则更新。每更新一次,对应的version加1.
好了,在次,使用以下命令,应该能够查询到一条记录了。

curl -XGET 'http://localhost:9200/twitter/tweet/1'  

delete(删除)

有了增加的例子,删除的例子也就好写了。增加是prepareIndex,删除是prepareDelete,查询就是PrepareGet。
代码如下:

1import org.elasticsearch.action.delete.DeleteResponse; 2import org.elasticsearch.client.Client; 3import org.elasticsearch.client.transport.TransportClient; 4import org.elasticsearch.common.settings.ImmutableSettings; 5import org.elasticsearch.common.settings.Settings; 6import org.elasticsearch.common.transport.InetSocketTransportAddress; 7 8import com.donlianli.es.ESUtils; 9 10public class DeleteTest { 11 public static void main(String[] argv){ 12 Settings settings = ImmutableSettings.settingsBuilder() 13 //指定集群名称 14 .put("cluster.name", "elasticsearch") 15 //探测集群中机器状态 16 .put("client.transport.sniff", true).build(); 17 /* * 创建客户端,所有的操作都由客户端开始,这个就好像是JDBC的Connection对象 * 用完记得要关闭 */ 18 Client client = new TransportClient(settings) 19 .addTransportAddress(new InetSocketTransportAddress("192.168.1.106", 9300)); 20 //在这里创建我们要索引的对象 21 DeleteResponse response = client.prepareDelete("twitter", "tweet", "1") 22 .execute().actionGet(); 23 System.out.println(response.getId()); 24 System.out.println(ESUtils.toJson(response.getHeaders())); 25 } 26}

GET(查询)

1import org.elasticsearch.action.get.GetResponse; 2import org.elasticsearch.client.Client; 3import org.elasticsearch.client.transport.TransportClient; 4import org.elasticsearch.common.settings.ImmutableSettings; 5import org.elasticsearch.common.settings.Settings; 6import org.elasticsearch.common.transport.InetSocketTransportAddress; 7 8public class GetTest { 9 public static void main(String[] argv){ 10 Settings settings = ImmutableSettings.settingsBuilder() 11 //指定集群名称 12 .put("cluster.name", "elasticsearch") 13 //探测集群中机器状态 14 .put("client.transport.sniff", true).build(); 15 /* * 创建客户端,所有的操作都由客户端开始,这个就好像是JDBC的Connection对象 * 用完记得要关闭 */ 16 Client client = new TransportClient(settings) 17 .addTransportAddress(new InetSocketTransportAddress("192.168.1.106", 9300)); 18 //在这里创建我们要索引的对象 19 GetResponse response = client.prepareGet("twitter", "tweet", "1") 20 .execute().actionGet(); 21 System.out.println("response.getId():"+response.getId()); 22 System.out.println("response.getSourceAsString():"+response.getSourceAsString()); 23 } 24}

好了,增删改查的代码写完。至于搜索,那是一个比较深入的话题,我也在慢慢探索。我时间我会继续写下去。

对于ES的Java Client我觉得更多的是类似于JDBC连接池的概念。你不能在程序里不停的new client,所有的连接都可以使用同一个client来操作,类似于我们在JDBC里每一次的查询都会使用同一个连接池。极端情况下不断的实例化client会导致服务器达到最大连接数,从而是应用报错。根据经验,默认情况下client保留的连接数是15。

如有不同见解,欢迎留言讨论!

原文出自http://donlianli.iteye.com/blog/1902238

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

Python之time模块的时间戳、时间字符串格式化与转换

Python处理时间和时间戳的内置模块就有time,和datetime两个,本文先说time模块。关于时间戳的几个概念时间戳,根据1970年1月1日00:00:00开始按秒计算的偏移量。时间元组(struct_time),包含9个元素。 time.struct_time(tm_y