在使用Eleasticsearch进行索引维护的过程中,如果你的应用场景需要频繁的大批量的索引写入,再使用上篇中提到的维护方法的话显然效率是低下的,此时推荐使用bulkIndex来提升效率。批写入数据块的大小取决于你的数据集及集群的配置。
下面我们以Spring Boot结合Elasticsearch创建一个示例项目,从基本的pom配置开始
<dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>1.4</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId></dependency>
application.properties配置
#elasticsearch configspring.data.elasticsearch.cluster-name:elasticsearchspring.data.elasticsearch.cluster-nodes:192.168.1.105:9300#application configserver.port=8080spring.application.name=esp-app
我们需要定义域的实体和一个Spring data的基本的CRUD支持库类。用id注释定义标识符字段,如果你没有指定ID字段,Elasticsearch不能索引你的文件。同时需要指定索引名称类型,@Document注解也有助于我们设置分片和副本数量。
@Data@Document(indexName = "carIndex", type = "carType", shards = 1, replicas = 0)public class Car implements Serializable {/*** serialVersionUID:* @since JDK 1.6*/private static final long serialVersionUID = 1L;@Idprivate Long id;private String brand;private String model;private BigDecimal amount;public Car(Long id, String brand, String model, BigDecimal amount) {this.id = id;this.brand = brand;this.model = model;this.amount = amount;}}
接着定义一个IndexService并使用bulk请求来处理索引,操作前首先要判断索引是否存在,以免出现异常。为了更好的掌握Java API,这里采用了不同于上篇中ElasticSearchRepository的ElasticSearchTemplate工具集,相对来讲功能更加丰富。
@Servicepublic class IndexerService {private static final String CAR_INDEX_NAME = "car_index";private static final String CAR_INDEX_TYPE = "car_type";@AutowiredElasticsearchTemplate elasticsearchTemplate;public long bulkIndex() throws Exception {int counter = 0;try {//判断索引是否存在if (!elasticsearchTemplate.indexExists(CAR_INDEX_NAME)) {elasticsearchTemplate.createIndex(CAR_INDEX_NAME);}Gson gson = new Gson();List<IndexQuery> queries = new ArrayList<IndexQuery>();List<Car> cars = assembleTestData();for (Car car : cars) {IndexQuery indexQuery = new IndexQuery();indexQuery.setId(car.getId().toString());indexQuery.setSource(gson.toJson(car));indexQuery.setIndexName(CAR_INDEX_NAME);indexQuery.setType(CAR_INDEX_TYPE);queries.add(indexQuery);//分批提交索引if (counter % 500 == 0) {elasticsearchTemplate.bulkIndex(queries);queries.clear();System.out.println("bulkIndex counter : " + counter);}counter++;}//不足批的索引最后不要忘记提交if (queries.size() > 0) {elasticsearchTemplate.bulkIndex(queries);}elasticsearchTemplate.refresh(CAR_INDEX_NAME);System.out.println("bulkIndex completed.");} catch (Exception e) {System.out.println("IndexerService.bulkIndex e;" + e.getMessage());throw e;}return -1;}private List<Car> assembleTestData() {List<Car> cars = new ArrayList<Car>();//随机生成10000个索引,以便下一次批量写入for (int i = 0; i < 10000; i++) {cars.add(new Car(RandomUtils.nextLong(1, 11111), RandomStringUtils.randomAscii(20), RandomStringUtils.randomAlphabetic(15), BigDecimal.valueOf(78000)));}return cars;}}
再下面的工作就比较简单了,可以编写一个RestController接受请求来测试或者CommandLineRunner,在系统启动时就加载上面的方法。
@SpringBootApplication@RestControllerpublic class ESPApplicatoin {public static void main(String[] args) {SpringApplication.run(ESPApplicatoin.class, args);}@AutowiredIndexerService indexService;@RequestMapping(value = "bulkIndex",method = RequestMethod.POST)public void bulkIndex(){try {indexService.bulkIndex();} catch (Exception e) {e.printStackTrace();}}}
CommandLineRunner方法类:
@Componentpublic class AppLoader implements CommandLineRunner {@AutowiredIndexerService indexerService;@Overridepublic void run(String... strings) throws Exception {indexerService.bulkIndex();}}
结束后,就可在通过地址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实现高性能动态网页展现
歪脖贰点零 ∣迭代当下 · 架构未来
程序员,除了编码,生活还应该有沉淀!
长按,识别二维码,加关注
本文分享自微信公众号 - 码闻强识(mavenTalk)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。



