(十五)使用Java操作Elasticsearch

本文作者:罗海鹏,叩丁狼高级讲师。原创文章,转载请注明出处。

前言

  到目前为止,我们一直都是使用RESTful风格的 API操作elasticsearch服务,但是通过我们之前的学习知道,elasticsearch提供了很多语言的客户端用于操作elasticsearch服务,例如:java、python、.net、JavaScript、PHP等。而我们此次就学习如何使用java语言来操作elasticsearch服务。在elasticsearch的官网上提供了两种java语言的API,一种是Java Transport Client,一种是Java REST Client。
  而Java REST Client又分为Java Low Level REST Client和Java High Level REST Client,Java High Level REST Client是在Java Low Level REST Client的基础上做了封装,使其以更加面向对象和操作更加便利的方式调用elasticsearch服务。
  官方推荐使用Java High Level REST Client,因为在实际使用中,Java Transport Client在大并发的情况下会出现连接不稳定的情况。
  那接下来我们就来看看elasticsearch提供的Java High Level REST Client(以下简称高级REST客户端)的一些基础的操作,跟多的操作大家自行阅读elasticsearch的官方文档:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high.html在官网上已经对高级REST客户端的各种API做了很详细的使用说明,我们这篇文章主要还是翻译官网上的内容,先让大家以更友好的中文文档方式入门,等大家熟悉了这些API之后在查阅官网。

测试项目

  在这里我也做了一个高级REST客户端的使用测试,该测试项目使用springboot开发,并且使用反射和泛型做了简易的封装,加强通用性。该项目的GitHub地址在以下链接:

https://github.com/luohaipeng/es-java-api

高级REST客户端使用

导入依赖

我们这里以maven为例,使用高级REST客户端需要两个依赖,分别是:

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

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

这两个依赖的版本是跟elasticsearch服务版本同步更新的,所以选择的依赖版本无需按照我这里的版本,而是以自己的elasticsearch服务的版本为主。

初始化

首先,我们想要操作elasticsearch,那必须先创建出连接的客户端对象,创建客户端对象的API如下:

        String[] ips = {"192.168.85.133:9200","192.168.85.133:9400"}
        HttpHost[] httpHosts = new HttpHost[ips.length];
        for(int i=0;i<ips.length;i++){
            httpHosts[i] = HttpHost.create(ips[i]);
        }
        RestClientBuilder builder = RestClient.builder(httpHosts);
        RestHighLevelClient client = new RestHighLevelClient(builder);

得到的RestHighLevelClient对象就是我们接下来操作elasticsearch所需要的了。

插入和更新文档操作

插入和更新文档需要我们构建一个IndexRequest对象。

  • 构造方法:IndexRequest(String index, String type, String id)第一个参数是该文档插入到哪个索引中,第二个参数是该文档插入到哪个文档类型中,第三个参数是指定文档的id。
  • 设置文档内容方法:source()该方法有多个重载方法,我们可以把文档内容以json字符串的方式传递,也可以以xml方式传递,还可以用Map方式传递。
  • 更新文档操作:调用高级REST客户端的index方法,并传入IndexRequest对象。
    具体代码如下:
public void insertOrUpdate(Object o) throws Exception {
        Map map = BeanUtil.bean2Map(o);
        IndexRequest request = new IndexRequest(baseIndex, baseType, map.get("id")+"");
        request.source(map);
        client.index(request);
    }

通过文档id删除文档

删除文档操作需要创建DeleteRequest对象。

  • 构造方法:常用的构造方法:DeleteRequest(String index, String type, String id)第一个参数代表将要删除的该文档所在的索引,第二个参数代表将要删除的索引所在的文档类型,第三个参数代表要删除的文档对应的id
  • 删除文档:调用高级REST客户端的delete方法,并传入DeleteRequest对象。
    具体代码如下:
public void delete(Long id) throws Exception {
        DeleteRequest request = new DeleteRequest(baseIndex, baseType, id + "");
        client.delete(request);
    }

通过文档id获取文档

通过文档id获取文档需要创建GetRequest对象。

  • 构造方法:常用构造方法:GetRequest(String index, String type, String id)第一个参数代表要获取的文档所在的索引,第二个参数代表要获取的索引所在的文档类型,第三个参数代表要获取的文档对应的id
  • 获取文档:调用高级REST客户端的get方法,并传入GetRequest对象。
  • 返回结果:返回GetResponse对象,可以使用该对象的getSource()方法,获得文档数据,该数据封装成Map对象。
    具体代码如下:
public T get(Long id) throws Exception {
        GetRequest request = new GetRequest(baseIndex, baseType, id+"");
        GetResponse response = client.get(request);
        Map<String, Object> source = response.getSource();
        T t = BeanUtil.map2Bean(source, clazz);
        return t;
    }

搜索文档

搜索文档需要创建SearchRequest对象。

  • 设置搜索的索引:indices(String... indices),elasticsearch允许对多个索引一起搜索,所以SearchRequest对象中的indices方法可以设置多个索引。
  • 设置搜索的文档类型:types(String... types),elasticsearch允许对多个文档类型一起搜索,所以SearchRequest对象中的types方法可以设置多个文档类型。
  • 设置搜索条件:搜索条件需要封装在SearchSourceBuilder对象中,我们只需要new SearchSourceBuilder()出该对象出来,然后为该对象设置搜索条件和数据范围相关参数即可。数据范围由from(int from)方法和 size(int size)方法指定。搜索条件由query(QueryBuilder query)方法设置。QueryBuilder对象就是最终封装搜索条件的对象,一个搜索条件就需要创建出一个该对象,该对象不需要我们手动创建,可以从QueryBuilders获取,QueryBuilders定义了各种搜索匹配的方式,我们只需要传入搜索的文档字段即可。
  • 设置搜索关键字高亮:当我们输入关键字搜索,如果能搜索出相应的文档,那一般我们都会在该文档上,把匹配到的关键字高亮显示,设置高亮显示的对象为HighlightBuilder,该对象有两个方法,preTags()高亮前缀,postTags()高亮后缀,通过这两个前缀和后缀,把搜索匹配到的文档中,出现的搜索关键字的地方包裹起来,实现高亮的效果。创建出来的HighlightBuilder设置到SearchSourceBuilder中。然后SearchSourceBuilder又设置到SearchRequest对象中。
  • 搜索:调用高级REST客户端的search方法,并传入SearchRequest对象。
  • 返回结果:返回SearchResponse对象,调用该对象的getHits()方法,获取返回结果,并最终转为我们自己的业务Page对象。
    具体代码如下:
public PageResult search(QueryObject qo) throws Exception {
        SearchRequest request = new SearchRequest();
        request.indices(baseIndex);
        request.types(baseType);
        SearchSourceBuilder sourceBuilder = qo.createSearchSourceBuilder();
        HighlightBuilder highlightBuilder = qo.createHighlightBuilder();
        sourceBuilder.highlighter(highlightBuilder);
        request.source(sourceBuilder);
        SearchResponse response = client.search(request);
        SearchHits searchHits = response.getHits();
        long total = searchHits.getTotalHits();
        SearchHit[] searchHitArray = searchHits.getHits();
        List<T> data = new ArrayList<>();
        for(SearchHit hit : searchHitArray){
            Map<String, Object> source = hit.getSourceAsMap();
            T t = BeanUtil.map2Bean(source, clazz);
            qo.setHighlightFields(t,hit);
            data.add(t);
        }
        return new PageResult(data,Integer.parseInt(total+""),qo.getCurrentPage(),qo.getPageSize());

    }

想获取更多技术干货,请前往叩丁狼官网:http://www.wolfcode.cn/all_article.html

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容

  • 前言   到目前为止,我们一直都是使用RESTful风格的 API操作elasticsearch服务,但是通过我们...
    LuoHaiPeng阅读 1,348评论 3 9
  • 说明 在明确了ES的基本概念和使用方法后,我们来学习如何使用ES的Java API.本文假设你已经对ES的基本概念...
    epicGeek阅读 43,560评论 4 44
  • 神话是普遍存在的吗?神话是真实的吗?神话被看作是故事,神话故事首先讲的是世界的创造,其他的,算作传说或者是民间故事...
    津城燕窝Donna阅读 355评论 0 0
  • 一直想记下关于懒虫的流水账,真正开始行动是从看一本小说后,发现写自己的虽事情与想法也是一有趣的事。懒虫的语句不够优...
    猫十月阅读 238评论 0 2
  • 事实上是我们没办法像正常异地恋情侣那样时常或是偶尔见面,没能承认和证明彼此的存在,尴尬的处在这样的情感关系中,面对...