在使用Eleasticsearch进行索引维护的过程中,如果你的应用场景需要频繁的大批量的索引写入,再使用上篇中提到的维护方法的话显然效率是低下的,此时推荐使用bulkIndex来提升效率。批写入数据块的大小取决于你的数据集及集群的配置。

下面我们以Spring Boot结合Elasticsearch创建一个示例项目,从基本的pom配置开始

  1. <dependency>
  2.    <groupId>com.google.code.gson</groupId>
  3.    <artifactId>gson</artifactId>
  4.    <version>1.4</version>
  5. </dependency>
  6. <dependency>
  7.    <groupId>org.springframework.boot</groupId>
  8.    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
  9. </dependency>

application.properties配置

  1. #elasticsearch config
  2. spring.data.elasticsearch.cluster-name:elasticsearch
  3. spring.data.elasticsearch.cluster-nodes:192.168.1.105:9300
  4. #application config
  5. server.port=8080
  6. spring.application.name=esp-app

我们需要定义域的实体和一个Spring data的基本的CRUD支持库类。用id注释定义标识符字段,如果你没有指定ID字段,Elasticsearch不能索引你的文件。同时需要指定索引名称类型,@Document注解也有助于我们设置分片和副本数量。

  1. @Data
  2. @Document(indexName = "carIndex", type = "carType", shards = 1, replicas = 0)
  3. public class Car implements Serializable {
  4.    /**
  5.     * serialVersionUID:
  6.     * @since JDK 1.6
  7.     */
  8.    private static final long serialVersionUID = 1L;
  9.    @Id
  10.    private Long id;
  11.    private String brand;
  12.    private String model;
  13.    private BigDecimal amount;
  14.    public Car(Long id, String brand, String model, BigDecimal amount) {
  15.        this.id = id;
  16.        this.brand = brand;
  17.        this.model = model;
  18.        this.amount = amount;
  19.    }
  20. }

接着定义一个IndexService并使用bulk请求来处理索引,操作前首先要判断索引是否存在,以免出现异常。为了更好的掌握Java API,这里采用了不同于上篇中ElasticSearchRepository的ElasticSearchTemplate工具集,相对来讲功能更加丰富。

  1. @Service
  2. public class IndexerService {
  3.    private static final String CAR_INDEX_NAME = "car_index";
  4.    private static final String CAR_INDEX_TYPE = "car_type";
  5.    @Autowired
  6.    ElasticsearchTemplate elasticsearchTemplate;
  7.    public long bulkIndex() throws Exception {
  8.        int counter = 0;
  9.        try {
  10.            //判断索引是否存在
  11.            if (!elasticsearchTemplate.indexExists(CAR_INDEX_NAME)) {
  12.                elasticsearchTemplate.createIndex(CAR_INDEX_NAME);
  13.            }
  14.            Gson gson = new Gson();
  15.            List<IndexQuery> queries = new ArrayList<IndexQuery>();
  16.            List<Car> cars = assembleTestData();
  17.            for (Car car : cars) {
  18.                IndexQuery indexQuery = new IndexQuery();
  19.                indexQuery.setId(car.getId().toString());
  20.                indexQuery.setSource(gson.toJson(car));
  21.                indexQuery.setIndexName(CAR_INDEX_NAME);
  22.                indexQuery.setType(CAR_INDEX_TYPE);
  23.                queries.add(indexQuery);
  24.                //分批提交索引
  25.                if (counter % 500 == 0) {
  26.                    elasticsearchTemplate.bulkIndex(queries);
  27.                    queries.clear();
  28.                    System.out.println("bulkIndex counter : " + counter);
  29.                }
  30.                counter++;
  31.            }
  32.            //不足批的索引最后不要忘记提交
  33.            if (queries.size() > 0) {
  34.                elasticsearchTemplate.bulkIndex(queries);
  35.            }
  36.            elasticsearchTemplate.refresh(CAR_INDEX_NAME);
  37.            System.out.println("bulkIndex completed.");
  38.        } catch (Exception e) {
  39.            System.out.println("IndexerService.bulkIndex e;" + e.getMessage());
  40.            throw e;
  41.        }
  42.        return -1;
  43.    }
  44.    private List<Car> assembleTestData() {
  45.        List<Car> cars = new ArrayList<Car>();
  46.        //随机生成10000个索引,以便下一次批量写入
  47.        for (int i = 0; i < 10000; i++) {
  48.            cars.add(new Car(RandomUtils.nextLong(1, 11111), RandomStringUtils.randomAscii(20), RandomStringUtils.randomAlphabetic(15), BigDecimal.valueOf(78000)));
  49.        }
  50.        return cars;
  51.    }
  52. }

再下面的工作就比较简单了,可以编写一个RestController接受请求来测试或者CommandLineRunner,在系统启动时就加载上面的方法。

  1. @SpringBootApplication
  2. @RestController
  3. public class ESPApplicatoin {
  4.    public static void main(String[] args) {
  5.        SpringApplication.run(ESPApplicatoin.class, args);
  6.    }
  7.    @Autowired
  8.    IndexerService indexService;
  9.    @RequestMapping(value = "bulkIndex",method = RequestMethod.POST)
  10.    public void bulkIndex(){
  11.        try {
  12.            indexService.bulkIndex();
  13.        } catch (Exception e) {
  14.            e.printStackTrace();
  15.        }
  16.    }
  17. }

CommandLineRunner方法类:

  1. @Component
  2. public class AppLoader implements CommandLineRunner {
  3.    @Autowired
  4.    IndexerService indexerService;
  5.    @Override
  6.    public void run(String... strings) throws Exception {
  7.        indexerService.bulkIndex();
  8.    }
  9. }

结束后,就可在通过地址http://localhost:9200/car_index/_search/来查看索引到底有无生效。注:要特别关注版本的兼容问题,如果用Es
5+的话,显然不能采用Spring Data Elasticsearch的方式。

Spring Boot

Version (x)

Spring Data Elasticsearch Version (y) Elasticsearch Version (z)
x <= 1.3.5 y <= 1.3.4 z <= 1.7.2*
x >= 1.4.x 2.0.0 <=y < 5.0.0** 2.0.0 <= z < 5.0.0**

(*) - require manual change in your project pom file (solution 2.)

(**) - Next big ES release with breaking changes

>>>案例地址:https://github.com/backkoms/spring-boot-elasticsearch

扩展阅读:

Spring
Boot + Elasticsearch 实现索引的日常维护

基于SpringCloud的Microservices架构实战案例-序篇

Nginx+Lua+MySQL/Redis实现高性能动态网页展现

Nginx+Lua+Redis实现高性能缓存数据读取

Spring Boot + Elasticsearch 实现索引批量写入的更多相关文章

  1. Spring Boot + Elasticsearch 实现索引的日常维护

    全文检索的应用越来越广泛,几乎成了互联网应用的标配,商品搜索.日志分析.历史数据归档等等,各种场景都会涉及到大批量的数据,在全文检索方面,方案无外乎Lucene.Solr.Elasticsearch三 ...

  2. Spring Boot + Elasticsearch实现大批量数据集下中文的精确匹配-案例剖析

    缘由 数据存储在MYSQ库中,数据基本维持不变,但数据量又较大(几千万)放在MYSQL中查询效率上较慢,寻求一种简单有效的方式提高查询效率,MYSQL并不擅长大规模数据量下的数据查询. 技术方案 考虑 ...

  3. 搭建spring boot+elasticsearch+activemq服务

    目前时间是:2017-01-24 本文不涉及activemq的安装 需求 activemq实时传递数据至服务 elasticsearch做索引 对外开放查询接口 完成全文检索 环境 jdk:1.8 s ...

  4. Spring Boot + Elasticsearch

    spring data elasticsearch elasticsearch 2.0.0.RELEASE 2.2.0 1.4.0.M1 1.7.3 1.3.0.RELEASE 1.5.2 1.2.0 ...

  5. spring boot使用log4j2将日志写入mysql数据库

    log4j2官方例子在spring boot中报错而且还是用的是org.apache.commons.dbcp包 我给改了一下使用org.apache.commons.dbcp2包 1.log4j2. ...

  6. Spring Boot + Elasticsearch 使用示例

    本文分别使用 Elasticsearch Repository 和 ElasticsearchTemplate 实现 Elasticsearch 的简单的增删改查 一.Elastic Stack El ...

  7. Spring Boot 增加删除修改 批量

    1.批量删除  a.自定义Repositoy中写 前台处理https://blog.csdn.net/yhflyl/article/details/81557670首先前台先要获取所有的要删除数据的I ...

  8. 在线elasticsearch集群批量写入变慢,导致kafka消息消费延迟

    写入报错如些: -- ::24.166 [elasticsearch[_client_][listener][T#1]] INFO com.mobanker.framework.es.Elastics ...

  9. 。。。。。。不带http https : 不报错 spring boot elasticsearch rest

    ......不带http https  : 不报错 先telnet http://onf:8080/getES653/道路桥梁正在“理疗”%20这14条道路纳入市政中修 @GetMapping(&qu ...

随机推荐

  1. php判断是否是移动设备

    function isMobile() { // 如果有HTTP_X_WAP_PROFILE则一定是移动设备 if (isset($_SERVER['HTTP_X_WAP_PROFILE'])) { ...

  2. 动态加载并执行Win32可执行程序

    本文所贴出的PoC代码将告诉你如何通过CreateProcess创建一个傀儡进程(称之为可执行程序A),并把dwCreationFlags设置为CREATE_SUSPENDED,然后把另一个可执行程序 ...

  3. C++中构造函数能调用虚函数吗?(答案是语法可以,输出错误),但Java里居然可以

    环境:XPSP3 VS2005 今天黑总给应聘者出了一个在C++的构造函数中调用虚函数的问题,具体的题目要比标题复杂,大体情况可以看如下的代码: class Base { public: Base() ...

  4. 把#define宏转换成指定格式

    之前在弄一个东西的,有一大堆的宏,需要把它转换成其它的形式.遇到这种大批量的东西,我特别没有耐心去一个一个的弄,于是写了一段代码. 估计大家平常比较难用得上,不过可以平常相似的情况用来参考. Sort ...

  5. C#获取应用路径的一些方法

    // 获取程序的基目录. System.AppDomain.CurrentDomain.BaseDirectory // 获取模块的完整路径. System.Diagnostics.Process.G ...

  6. ASP.NET MVC控制器Controller中参数

    前述文章参见:ASP.NET MVC控制器Controller 绪论 之前的控制器返回的均为常量字符串,接下来展示如何获取请求传来的参数,而返回"动态"的字符串. 可以在操作方法B ...

  7. virtualbox ubuntu16.04 自动挂载共享文件夹

    为了操作方便,需要ubuntu 在开机运行时自动挂载共享文件夹,ubuntu的版本是16.04,宿主机是win10,步骤如下: 1. 在virtualbox “设备”-“共享文件夹”中设置共享文件夹如 ...

  8. 基于QT的在线打字练习软件助手(C/S模型)good

    简介   通过基于QT中QTcpServer和QTcpSocket以及UI编程,实现了基于TCP协议的C/S模型在线打字练习软件助手,服务端处理各客户端打字数据,以及显示在线打字客户列表即实时更新打字 ...

  9. SpringBoot中资源初始化加载的几种方式(看这一片就够了)

    一.问题 在平时的业务模块开发过程中,难免会需要做一些全局的任务.缓存.线程等等的初始化工作,那么如何解决这个问题呢?方法有多种,但具体又要怎么选择呢? 二.资源初始化 1.既然要做资源的初始化,那么 ...

  10. MyBatis从入门到精通(二):MyBatis XML方式的基本用法之Select

    最近在读刘增辉老师所著的<MyBatis从入门到精通>一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸! 1. 明确需求 书中提到的需求是一个基 ...