Spring Boot + Elasticsearch 实现索引批量写入

Spring Boot + Elasticsearch 实现索引批量写入

在使用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.  

  5. #application config

  6. server.port=8080

  7. 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.  

  15.    public Car(Long id, String brand, String model, BigDecimal amount) {

  16.        this.id = id;

  17.        this.brand = brand;

  18.        this.model = model;

  19.        this.amount = amount;

  20.    }

  21. }

接着定义一个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.  

  8.    public long bulkIndex() throws Exception {

  9.        int counter = 0;

  10.        try {

  11.            //判断索引是否存在

  12.            if (!elasticsearchTemplate.indexExists(CAR_INDEX_NAME)) {

  13.                elasticsearchTemplate.createIndex(CAR_INDEX_NAME);

  14.            }

  15.            Gson gson = new Gson();

  16.            List<IndexQuery> queries = new ArrayList<IndexQuery>();

  17.            List<Car> cars = assembleTestData();

  18.            for (Car car : cars) {

  19.                IndexQuery indexQuery = new IndexQuery();

  20.                indexQuery.setId(car.getId().toString());

  21.                indexQuery.setSource(gson.toJson(car));

  22.                indexQuery.setIndexName(CAR_INDEX_NAME);

  23.                indexQuery.setType(CAR_INDEX_TYPE);

  24.                queries.add(indexQuery);

  25.                //分批提交索引

  26.                if (counter % 500 == 0) {

  27.                    elasticsearchTemplate.bulkIndex(queries);

  28.                    queries.clear();

  29.                    System.out.println("bulkIndex counter : " + counter);

  30.                }

  31.                counter++;

  32.            }

  33.            //不足批的索引最后不要忘记提交

  34.            if (queries.size() > 0) {

  35.                elasticsearchTemplate.bulkIndex(queries);

  36.            }

  37.            elasticsearchTemplate.refresh(CAR_INDEX_NAME);

  38.            System.out.println("bulkIndex completed.");

  39.        } catch (Exception e) {

  40.            System.out.println("IndexerService.bulkIndex e;" + e.getMessage());

  41.            throw e;

  42.        }

  43.  

  44.        return -1;

  45.    }

  46.  

  47.    private List<Car> assembleTestData() {

  48.        List<Car> cars = new ArrayList<Car>();

  49.        //随机生成10000个索引,以便下一次批量写入

  50.        for (int i = 0; i < 10000; i++) {

  51.            cars.add(new Car(RandomUtils.nextLong(1, 11111), RandomStringUtils.randomAscii(20), RandomStringUtils.randomAlphabetic(15), BigDecimal.valueOf(78000)));

  52.        }

  53.        return cars;

  54.    }

  55. }

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

 
  1. @SpringBootApplication

  2. @RestController

  3. public class ESPApplicatoin {

  4.  

  5.    public static void main(String[] args) {

  6.        SpringApplication.run(ESPApplicatoin.class, args);

  7.    }

  8.  

  9.    @Autowired

  10.    IndexerService indexService;

  11.  

  12.  

  13.    @RequestMapping(value = "bulkIndex",method = RequestMethod.POST)

  14.    public void bulkIndex(){

  15.        try {

  16.            indexService.bulkIndex();

  17.        } catch (Exception e) {

  18.            e.printStackTrace();

  19.        }

  20.    }

  21. }

CommandLineRunner方法类:

 
  1. @Component

  2. public class AppLoader implements CommandLineRunner {

  3.    @Autowired

  4.    IndexerService indexerService;

  5.  

  6.    @Override

  7.    public void run(String... strings) throws Exception {

  8.        indexerService.bulkIndex();

  9.    }

  10. }

结束后,就可在通过地址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.5y <= 1.3.4z <= 1.7.2*
x >= 1.4.x2.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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现索引擎一般需要以下步骤: 1. 数据库建表和数据导入:根据需要建立相应的数据库表,并导入数据。 2. Elasticsearch安装和配置:安装Elasticsearch,配置Elasticsearch集群,并将数据导入到Elasticsearch中。 3. Spring Boot和Vue.js项目搭建:使用Spring Boot和Vue.js框架搭建项目。 4. 搜索功能实现:使用Elasticsearch进行搜索功能的实现。 具体实现步骤如下: 1. 数据库建表和数据导入 根据需求建立相应的数据库表,并将数据导入到数据库中。这里以MySQL为例,建立一个books表: CREATE TABLE `books` ( `id` int NOT NULL AUTO_INCREMENT, `title` varchar(255) DEFAULT NULL, `author` varchar(255) DEFAULT NULL, `content` text, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 将数据导入到books表中: INSERT INTO `books` (`id`, `title`, `author`, `content`) VALUES (1, 'Java编程思想', 'Bruce Eckel', 'Java编程思想是一本Java入门书籍。'), (2, 'Spring Boot实战', 'Craig Walls', 'Spring Boot实战是一本介绍Spring Boot框架的书籍。'), (3, 'Vue.js实战', '梁灏', 'Vue.js实战是一本介绍Vue.js框架的书籍。'); 2. Elasticsearch安装和配置 安装Elasticsearch,配置Elasticsearch集群,并将数据导入到Elasticsearch中。这里以Elasticsearch 7.2.0为例,安装步骤如下: (1)下载Elasticsearch 官网下载地址:https://www.elastic.co/downloads/elasticsearch (2)解压并启动Elasticsearch 解压后进入bin目录,执行以下命令启动Elasticsearch: ./elasticsearch (3)安装中文分词器 Elasticsearch默认使用英文分词器,需要安装中文分词器,这里使用IK Analyzer中文分词器。IK Analyzer的GitHub地址为:https://github.com/medcl/elasticsearch-analysis-ik 下载IK Analyzer插件: wget https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.2.0/elasticsearch-analysis-ik-7.2.0.zip 将插件安装到Elasticsearch中: ./elasticsearch-plugin install file:///path/to/elasticsearch-analysis-ik-7.2.0.zip (4)将数据导入到Elasticsearch中 使用Elasticsearch的API将数据库中的数据导入到Elasticsearch中。 3. Spring Boot和Vue.js项目搭建 使用Spring Boot和Vue.js框架搭建项目,这里不再赘述。 4. 搜索功能实现 (1)在Spring Boot中使用Elasticsearch进行搜索 使用Spring Data Elasticsearch实现Elasticsearch的交互,具体步骤如下: 1. 在pom.xml中添加Spring Data Elasticsearch依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> 2. 在application.yml中配置Elasticsearchspring: data: elasticsearch: cluster-name: elasticsearch cluster-nodes: 127.0.0.1:9300 3. 创建一个Book实体类,并使用@Document注解标注该实体类对应的Elasticsearch索引和类型: @Document(indexName = "books", type = "book") public class Book { @Id private Long id; private String title; private String author; private String content; // getter和setter方法省略 } 4. 创建一个BookRepository接口,继承ElasticsearchRepository接口: public interface BookRepository extends ElasticsearchRepository<Book, Long> { } 5. 在BookService中实现搜索功能: @Service public class BookService { @Autowired private BookRepository bookRepository; public List<Book> search(String keyword) { QueryBuilder queryBuilder = QueryBuilders.multiMatchQuery(keyword, "title", "author", "content"); Iterable<Book> iterable = bookRepository.search(queryBuilder); List<Book> books = new ArrayList<>(); iterable.forEach(books::add); return books; } } (2)在Vue.js中调用搜索接口 使用axios库调用Spring Boot的接口,具体步骤如下: 1. 安装axios库: npm install axios --save 2. 在Vue.js中调用搜索接口: <script> import axios from 'axios'; export default { data() { return { keyword: '', books: [] } }, methods: { search() { axios.get('/api/search?keyword=' + this.keyword).then(response => { this.books = response.data; }).catch(error => { console.log(error); }); } } } </script> 以上就是使用Spring Boot和Vue.js实现Elasticsearch索引擎的步骤。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值