Spring Data Elasticsearch 的简单使用 时间: 2019-02-26 15:49 分类: JAVA ####前言 本实例只是用作快速入门使用,这段时间自己将 3 年前的`DHT网络爬虫`重新写了一遍,一来是因为之前的程序代码写的非常杂乱,性能也不是很好,数据到了1600万的时候就爬不动数据了;二来是借此实战一波 Spring Cloud 微服务的开发。 3年前用的`Mysql`存储数据,由于存储的数据字段长度比较大,所以此次决定直接拿`Elasticsearch`来当做数据库使用,集全文检索于一体,何乐而不为。 实战之前也是先搜索了一波`Elasticsearch`能不能当做数据库来使用,发现还是有人是这样来用的,所以暂且不管后面是否存在性能问题,是否有坑,也先实验一波再说。 ####集成 `Spring boot`项目需要添加如下依赖: ```xml org.springframework.boot spring-boot-starter-data-elasticsearch ``` `Elasticsearch`的安装在[前一篇文章][1]已经说过了,所以这里不再赘述。 `application.yml`中添加如下配置: ``` spring: data: elasticsearch: cluster-nodes: 127.0.0.1:9300 repositories: enabled: true properties: path: logs: ./elasticsearch/log #elasticsearch日志存储目录 data: ./elasticsearch/data #elasticsearch数据存储目录 ``` 接下来的使用就是`Spring data`系列的相同套路了,`Spring data`对各种数据库操作进行的封装都大同小异,依葫芦画瓢照着来创建`Repository`即可,既然是使用`Spring Data Elasticsearch`,那么我们新建的`Repository`接口就是继承`ElasticsearchRepository`接口了。 查看`ElasticsearchRepository`有哪些接口可供使用: ```java public interface ElasticsearchRepository extends ElasticsearchCrudRepository { S index(S var1); Iterable search(QueryBuilder var1); Page search(QueryBuilder var1, Pageable var2); Page search(SearchQuery var1); Page searchSimilar(T var1, String[] var2, Pageable var3); void refresh(); Class getEntityClass(); } ``` 可以看到它包含了几个搜索的接口和一个索引的接口,除此之外,它还继承了`ElasticsearchCrudRepository`,从名字上就可以知道它包含了一系列的`增删改查`接口,实际上它上面还继承了一系列的接口,这里我直接找到上面关键的一个接口类: ```java public interface CrudRepository extends Repository { S save(S var1); Iterable saveAll(Iterable var1); Optional findById(ID var1); boolean existsById(ID var1); Iterable findAll(); Iterable findAllById(Iterable var1); long count(); void deleteById(ID var1); void delete(T var1); void deleteAll(Iterable extends T> var1); void deleteAll(); } ``` 我们使用的时候只需要新建接口继承`ElasticsearchRepository`即可,无需添加注解,下面是我新建的一个`Repository`接口: ```java public interface TorrentRepository extends ElasticsearchRepository, TorrentDao { } ``` 上面的接口中我没有定义任何方法是因为我暂时还用不到其他方法,实际上它也支持`findByXXX`这种形式的接口定义,具体可参见[官方文档][2]。 除此之外,可以看到我上面还继承了`TorrentDao`,这是我以前使用`Spring Data JPA`时学习的自定义扩展`Repository`,也可以说是`Spring Data`操作数据库的高级用法,`Spring Data JPA`中就是操作`entityManager`来做更加复杂的查询。 在`Spring Data Elasticsearch`也是一样用法,可以直接使用`elasticsearchTemplate`来做高级操作。 比如我这里,继承的`ElasticsearchRepository`,里面包含的一些接口不能满足我的现有需求: > 数据库不存在则插入,存在则更新的操作(不知道 ElasticsearchRepository 中的 save() 方法是否能够做到) 所以选择使用`elasticsearchTemplate`来做高级操作。 用法如下,新建`TorrentDao`接口: ```java /*** * 自定义扩展 Torrent Dao * * @author Mr.Xu * @since 2019-02-25 11:07 **/ public interface TorrentDao { /** * 存在则更新,不存在则插入 * * @param torrent * @return void */ void upsert(Torrent torrent) throws IOException; } ``` 接着添加其实现类`TorrentDaoImpl.java`: ```java /*** * 自定义扩展 Torrent Dao 实现类 * * @author Mr.Xu * @since 2019-02-25 11:09 **/ public class TorrentDaoImpl implements TorrentDao { @Autowired private ElasticsearchTemplate template; @Override public void upsert(Torrent torrent) throws IOException { Client client = template.getClient(); XContentBuilder source = jsonBuilder() .startObject() .field("fileType", torrent.getFileType()) .field("filesize", torrent.getFilesize()) .field("createDate", torrent.getCreateDate()) .field("files", torrent.getFiles()) .endObject(); IndexRequest indexRequest = new IndexRequest("dodder", "torrent", torrent.getInfoHash()) .source(source); UpdateRequest updateRequest = new UpdateRequest("dodder", "torrent", torrent.getInfoHash()) .doc(source) .upsert(indexRequest); client.update(updateRequest); } } ``` 最后直接在继承`ElasticsearchRepository`接口的类也继承我们自定义的接口即可,如下: ```java public interface TorrentRepository extends ElasticsearchRepository, TorrentDao { } ``` [1]: https://0o0.me/db/elasticsearch-install.html [2]: https://docs.spring.io/spring-data/elasticsearch/docs/3.1.5.RELEASE/reference/html/ 标签: 无