ElasticSearchRepository和ElasticSearchTemplate的使用
Spring-data-elasticsearch是Spring提供的操作ElasticSearch的数据层,封装了大量的基础操作,通过它可以很方便的操作ElasticSearch的数据。
版本说明
ElasticSearch目前最新的已到5.5.1
spring data elasticsearch | elasticsearch |
---|---|
3.0.0.RC1 | 5.5.0 |
3.0.0.M4 | 5.4.0 |
2.0.4.RELEASE | 2.4.0 |
2.0.0.RELEASE | 2.2.0 |
1.4.0.M1 | 1.7.3 |
1.3.0.RELEASE | 1.5.2 |
1.2.0.RELEASE | 1.4.4 |
1.1.0.RELEASE | 1.3.2 |
1.0.0.RELEASE | 1.1.1 |
这有一个对应关系,不过不太完整,我目前使用的SpringBoot版本1.5.4对应的spring-data-ElasticSearch是2.1.4,在图上就没有体现。
但是可以预见对应的ElasticSearch应该在2.4.*往上,但应该是不支持5.4.0及以上。
注意:我这篇例子,所使用的ElasticSearch版本就是最新的5.5.1,SpringBoot版本是1.5.4,经初步试验,插入及查询都没问题。估计是5.5.*的新特性之类的会无法使用,基本操作应该都没问题。
ElasticSearchRepository的基本使用
@NoRepositoryBean
public interface ElasticsearchRepository<T, ID extends Serializable> extends ElasticsearchCrudRepository<T, ID> {
<S extends T> S index(S var1);
Iterable<T> search(QueryBuilder var1);
Page<T> search(QueryBuilder var1, Pageable var2);
Page<T> search(SearchQuery var1);
Page<T> searchSimilar(T var1, String[] var2, Pageable var3);
void refresh();
Class<T> getEntityClass();
}
我们是通过继承ElasticsearchRepository来完成基本的CRUD及分页操作的,和普通的JPA没有什么区别。
ElasticsearchRepository继承了ElasticsearchCrudRepository extends PagingAndSortingRepository.
public interface BookRepository extends Repository<Book, String> { List<Book> findByNameAndPrice(String name, Integer price); List<Book> findByNameOrPrice(String name, Integer price); Page<Book> findByName(String name,Pageable page); Page<Book> findByNameNot(String name,Pageable page); Page<Book> findByPriceBetween(int price,Pageable page); Page<Book> findByNameLike(String name,Pageable page); @Query("{\"bool\" : {\"must\" : {\"term\" : {\"message\" : \"?0\"}}}}") Page<Book> findByMessage(String message, Pageable pageable); }
这个没什么特点,就是普通的JPA查询,这个很熟悉,通过上面的JPA查询就能完成很多的基本操作了。
@Autowired private SampleElasticsearchRepository repository; String documentId = "123456"; SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setMessage("some message"); repository.save(sampleEntity);
还可以批量插入数据:
@Autowired private SampleElasticsearchRepository repository; String documentId = "123456"; SampleEntity sampleEntity1 = new SampleEntity(); sampleEntity1.setId(documentId); sampleEntity1.setMessage("some message"); String documentId2 = "123457" SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setMessage("test message"); List<SampleEntity> sampleEntities = Arrays.asList(sampleEntity1, sampleEntity2); //bulk index repository.save(sampleEntities);
public NativeSearchQuery(QueryBuilder query, QueryBuilder filter, List<SortBuilder> sorts, Field[] highlightFields) { this.query = query; this.filter = filter; this.sorts = sorts; this.highlightFields = highlightFields; }
当然了,我们没必要实现所有的参数。
double lat = 39.929986; double lon = 116.395645; Long nowTime = System.currentTimeMillis(); //查询某经纬度100米范围内 GeoDistanceQueryBuilder builder = QueryBuilders.geoDistanceQuery("address").point(lat, lon) .distance(100, DistanceUnit.METERS); GeoDistanceSortBuilder sortBuilder = SortBuilders.geoDistanceSort("address") .point(lat, lon) .unit(DistanceUnit.METERS) .order(SortOrder.ASC); Pageable pageable = new PageRequest(0, 50); NativeSearchQueryBuilder builder1 = new NativeSearchQueryBuilder().withFilter(builder).withSort(sortBuilder).withPageable(pageable); SearchQuery searchQuery = builder1.build();
要完成字符串的查询:
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.queryStringQuery("spring boot OR 书籍")).build();
要构建QueryBuilder,我们可以使用工具类QueryBuilders,里面有大量的方法用来完成各种各样的QueryBuilder的构建,字符串的、Boolean型的、match的、地理范围的等等。
ElasticSearchTemplate的使用
String documentId = "123456"; SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setMessage("some message"); IndexQuery indexQuery = new IndexQueryBuilder().withId(sampleEntity.getId()).withObject(sampleEntity).build(); elasticsearchTemplate.index(indexQuery);
add主要是通过index方法来完成,需要构建一个IndexQuery对象
public void bulkIndex(List<IndexQuery> queries) { BulkRequestBuilder bulkRequest = this.client.prepareBulk(); Iterator var3 = queries.iterator(); while(var3.hasNext()) { IndexQuery query = (IndexQuery)var3.next(); bulkRequest.add(this.prepareIndex(query)); } BulkResponse bulkResponse = (BulkResponse)bulkRequest.execute().actionGet(); if (bulkResponse.hasFailures()) { Map<String, String> failedDocuments = new HashMap(); BulkItemResponse[] var5 = bulkResponse.getItems(); int var6 = var5.length; for(int var7 = 0; var7 < var6; ++var7) { BulkItemResponse item = var5[var7]; if (item.isFailed()) { failedDocuments.put(item.getId(), item.getFailureMessage()); } } throw new ElasticsearchException("Bulk indexing has failures. Use ElasticsearchException.getFailedDocuments() for detailed messages [" + failedDocuments + "]", failedDocuments); } } public void bulkUpdate(List<UpdateQuery> queries) { BulkRequestBuilder bulkRequest = this.client.prepareBulk(); Iterator var3 = queries.iterator(); while(var3.hasNext()) { UpdateQuery query = (UpdateQuery)var3.next(); bulkRequest.add(this.prepareUpdate(query)); } BulkResponse bulkResponse = (BulkResponse)bulkRequest.execute().actionGet(); if (bulkResponse.hasFailures()) { Map<String, String> failedDocuments = new HashMap(); BulkItemResponse[] var5 = bulkResponse.getItems(); int var6 = var5.length; for(int var7 = 0; var7 < var6; ++var7) { BulkItemResponse item = var5[var7]; if (item.isFailed()) { failedDocuments.put(item.getId(), item.getFailureMessage()); } } throw new ElasticsearchException("Bulk indexing has failures. Use ElasticsearchException.getFailedDocuments() for detailed messages [" + failedDocuments + "]", failedDocuments); } }
和index插入单条数据一样,这里需要的是List<IndexQuery>仅此而已,是不是很简单。
public void bulkIndex(List<Person> personList) { int counter = 0; try { if (!elasticsearchTemplate.indexExists(PERSON_INDEX_NAME)) { elasticsearchTemplate.createIndex(PERSON_INDEX_TYPE); } List<IndexQuery> queries = new ArrayList<>(); for (Person person : personList) { IndexQuery indexQuery = new IndexQuery(); indexQuery.setId(person.getId() + ""); indexQuery.setObject(person); indexQuery.setIndexName(PERSON_INDEX_NAME); indexQuery.setType(PERSON_INDEX_TYPE); //上面的那几步也可以使用IndexQueryBuilder来构建 //IndexQuery index = new IndexQueryBuilder().withId(person.getId() + "").withObject(person).build(); 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); } System.out.println("bulkIndex completed."); } catch (Exception e) { System.out.println("IndexerService.bulkIndex e;" + e.getMessage()); throw e; } }
这里是创建了100万个Person对象,每到500就用bulkIndex插入一次,速度飞快,以秒的速度插入了百万数据。
ElasticSearchRepository和ElasticSearchTemplate的使用的更多相关文章
- springboot整合elasticsearch入门例子
springboot整合elasticsearch入门例子 https://blog.csdn.net/tianyaleixiaowu/article/details/72833940 Elastic ...
- windows下elasticsearch配置及spring boot 简单demod的 整合
学习过程: elasticsearch 下载安装 elasticsearch-head 安装 spring boot 下elasticsearch的配置 使用ElasticsearchReposito ...
- Spring Boot高级
Spring Boot高级内容概要一.Spring Boot与缓存二.Spring Boot与消息三.Spring Boot与检索四.Spring Boot与任务五.Spring Boot与安全六.S ...
- Spring Boot + Elasticsearch 实现索引批量写入
在使用Eleasticsearch进行索引维护的过程中,如果你的应用场景需要频繁的大批量的索引写入,再使用上篇中提到的维护方法的话显然效率是低下的,此时推荐使用bulkIndex来提升效率.批写入数据 ...
- spring Boot 学习(三、Spring Boot与检索)
一.检索我们的应用经常需要添加检索功能,开源的 ElasticSearch 是目前全文搜索引擎的 首选.他可以快速的存储.搜索和分析海量数据.Spring Boot通过整合Spring Data El ...
- elastic search book [ ElasticSearch book es book]
谁在使用ELK 维基百科, github都使用 ELK (ElasticSearch es book) ElasticSearch入门 Elasticsearch入门,这一篇就够了==>http ...
- SpringBoot笔记二:整合篇
Spring Boot与缓存 jsr-107 Java Caching定义了5个核心接口分别是CachingProvider, CacheManager, Cache, Entry 和 Expiry. ...
- elasticsearchTemplate that could not be found
***************************APPLICATION FAILED TO START*************************** Description: Metho ...
- Spring ElasticsearchTemplate 经纬度按距离排序
es实体,用 @GeoPointField 注解,值为:中间逗号隔开,如 29.477000,119.278536(经度, 维度) @Document(indexName = "v_inte ...
随机推荐
- [转载]Javassist 使用指南(三)
======================= 本文转载自简书,感谢原作者!. 原链接如下:https://www.jianshu.com/p/7803ffcc81c8 =============== ...
- DOS/BAT批处理if exist else 语句的几种用法
在DOS批处理命令中常常会通过if语句来进行判断来执行下面的命令, 那么批处理if语句怎么用呢,下面学无忧小编就来说说有关批处理if以及if exist else语句的相关内容.一.批处理if书写格式 ...
- 二进制转化 - bitset
2017-08-28 10:55:17 writer:pprp 在之前写了一个关于bitset用法的贴之后,这是第一次运用,不得不说如果不用的话还是一头雾水 以后写代码要标记开始时间,和结束时间了,我 ...
- 在ajax请求下的缓存机制
1.在服务端加 header(“Cache-Control: no-cache, must-revalidate”);2.在ajax发送请求前加上 anyAjaxObj.setRequestHeade ...
- vcf2maf
1.https://github.com/mskcc/vcf2maf 2.https://github.com/cbare/vcf2maf
- 一致性hash演示
看到点关于一致性hash的说明,觉得挺有意思,就想体验一下. 上代码看看,体会一下在一致性hash环境下的cache和获取. 因为是小代码演示,没有很细致,包括hash函数就是用取余操作,但活生生的显 ...
- [Mybatis]Spring与Mybatis整合的MapperScannerConfigurer处理过程源码分析
转自:https://www.cnblogs.com/fangjian0423/p/spring-mybatis-MapperScannerConfigurer-analysis.html Mappe ...
- c语言的tcp和udp客户端和服务器
都是最简单的用来记忆. this is my 的git地址:https://github.com/yanjinyun/cLanguageTcpUdp tcp最简单的服务器: int main(int ...
- spring mvc: 生成RSS源
spring mvc: 生成RSS源 准备: 从相同的maven存储库页面下载 Rome 库及其依赖项rome-utils,jdom和slf4j.和所需的依赖关系 <!-- rss源依赖 --& ...
- 使用lock锁或Monitor.Enter的目的
锁定的目的:由于多个线程 并行/并发 处理同一个“数据对象”(比如:在其它线程的某个地方发生了Clear.Add.Remove.Change等操作),导致“数据对象”不断变化,没法用了,所以,为了保证 ...