转自:https://blog.csdn.net/u013089490/article/details/84323903

1、ElasticsearchRepository

1.1、ElasticsearchRepository源码

Spring Data Elasticsearch篇(3):ElasticsearchRepository文档操作 - 图1

  1. @NoRepositoryBean
  2. public interface ElasticsearchRepository<T, ID extends Serializable> extends ElasticsearchCrudRepository<T, ID> {
  3. <S extends T> S index(S entity);
  4. Iterable<T> search(QueryBuilder query);
  5. //search方法需要QueryBuilder参数和springdata的Pageable分页参数
  6. //其中QueryBuilder是一个接口,常用的实现类有MatchQueryBuilder、RangeQueryBuilder范围、FuzzyQueryBuilder模糊、WildcardQueryBuilder模糊。
  7. Page<T> search(QueryBuilder query, Pageable pageable);
  8. //SearchQuery是一个查询接口,NativeSearchQuery是该接口的一个实现
  9. Page<T> search(SearchQuery searchQuery);
  10. Page<T> searchSimilar(T entity, String[] fields, Pageable pageable);
  11. void refresh();
  12. Class<T> getEntityClass();
  13. }

【注意】
(1)ElasticsearchRepository里面search(QueryBuilder query)方法,其中QueryBuilder是一个接口,常用的实现类有MatchQueryBuilder、RangeQueryBuilder范围、FuzzyQueryBuilder模糊、WildcardQueryBuilder模糊。
(2)ElasticsearchRepository里面search(SearchQuery searchQuery)方法,主要是看QueryBuilder和SearchQuery两个参数;其中SearchQuery是一个接口,有一个实现类叫NativeSearchQuery

1.2、自定义方法

  1. 自定义方法的前提是我们需要继承ElasticsearchRepository接口,利用强大的Spring Data来实现。比如:你的方法名叫做:findByTitle,那么它就知道你是根据title查询,然后自动帮你完成,无需写实现类。<br />【自定义方法命名约定】:
Keyword Sample Elasticsearch Query String
And findBy**NameAndPrice** {"bool" : {"**must**" : [ {"field" : {"name" : "?"}}, {"field" : {"price" : "?"}} ]}}
Or **findByNameOrPrice** {"bool" : {"**should**" : [ {"field" : {"name" : "?"}}, {"field" : {"price" : "?"}} ]}}
Is **findBy**Name {"bool" : {"**must**" : {"field" : {"name" : "?"}}}}
Not **findBy****Nam**eNot {"bool" : {"**must_not**" : {"field" : {"name" : "?"}}}}
Between **findBy****Price**Between {"bool" : {"**must**" : {"**range**" : {"price" : {"from" : ?,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}
LessThanEqual findByPriceLessThan {"bool" : {"must" : {"range" : {"price" : {"from" : null,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}
GreaterThanEqual findByPriceGreaterThan {"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : null,"include_lower" : true,"include_upper" : true}}}}}
Before findByPriceBefore {"bool" : {"must" : {"range" : {"price" : {"from" : null,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}
After findByPriceAfter {"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : null,"include_lower" : true,"include_upper" : true}}}}}
Like findByNameLike {"bool" : {"must" : {"field" : {"name" : {"query" : "?*","analyze_wildcard" : true}}}}}
StartingWith findByNameStartingWith {"bool" : {"must" : {"field" : {"name" : {"query" : "?*","analyze_wildcard" : true}}}}}
EndingWith findByNameEndingWith {"bool" : {"must" : {"field" : {"name" : {"query" : "*?","analyze_wildcard" : true}}}}}
Contains/Containing findByNameContaining {"bool" : {"must" : {"field" : {"name" : {"query" : "**?**","analyze_wildcard" : true}}}}}
In findByNameIn(Collection<String>names) {"bool" : {"must" : {"bool" : {"should" : [ {"field" : {"name" : "?"}}, {"field" : {"name" : "?"}} ]}}}}
NotIn findByNameNotIn(Collection<String>names) {"bool" : {"must_not" : {"bool" : {"should" : {"field" : {"name" : "?"}}}}}}
Near findByStoreNear Not Supported Yet !
True findByAvailableTrue {"bool" : {"must" : {"field" : {"available" : true}}}}
False findByAvailableFalse {"bool" : {"must" : {"field" : {"available" : false}}}}
OrderBy `findByAvailableTrueOrderByNameDesc` {"sort" : [{ "name" : {"order" : "desc"} }],"bool" : {"must" : {"field" : {"available" : true}}}}

例如,我们来按照价格区间查询,定义这样的一个方法findByPriceBetween:

  1. /**
  2. * 需要继承ElasticsearchRepository接口
  3. * 由于Item实体类中id为Long类型
  4. */
  5. public interface ItemRepository extends ElasticsearchRepository<Item,Long> {
  6. /**
  7. * 方法名必须遵守SpringData的规范
  8. * 价格区间查询
  9. */
  10. List<Item> findByPriceBetween(double price1, double price2);
  11. }

2、基本操作

在【https://mp.csdn.net/postedit/84323886】基础上我们进行以下操作,实体类和索引创建都是安装上述博客内容;下面只对Repository操作详细说明。

2.1、定义自己的Repository接口

  1. /**
  2. * 需要继承ElasticsearchRepository接口
  3. * 由于Item实体类中id为Long类型
  4. */
  5. public interface ItemRepository extends ElasticsearchRepository<Item,Long> {
  6. /**
  7. * 方法名必须遵守SpringData的规范
  8. * 价格区间查询
  9. */
  10. List<Item> findByPriceBetween(double price1, double price2);
  11. }

2.2、新增单条文档

添加单条文档数据使用的save()方法。

  1. @Autowired
  2. private ItemRepository itemRepository;
  3. @Test
  4. public void insert(){
  5. Item item = new Item(1L, "小米手机7", " 手机","小米", 3499.00, "http://image.leyou.com/13123.jpg");
  6. itemRepository.save(item);
  7. }

2.3、插入多条文档

插入多条文档数据使用的saveAll()方法。

  1. @Autowired
  2. private ItemRepository itemRepository;
  3. @Test
  4. public void indexList() {
  5. List<Item> list = new ArrayList<>();
  6. list.add(new Item(1L, "小米手机7", "手机", "小米", 3299.00, "http://image.leyou.com/13123.jpg"));
  7. list.add(new Item(2L, "坚果手机R1", "手机", "锤子", 3699.00, "http://image.leyou.com/13123.jpg"));
  8. list.add(new Item(3L, "华为META10", "手机", "华为", 4499.00, "http://image.leyou.com/13123.jpg"));
  9. list.add(new Item(4L, "小米Mix2S", "手机", "小米", 4299.00, "http://image.leyou.com/13123.jpg"));
  10. list.add(new Item(5L, "荣耀V10", "手机", "华为", 2799.00, "http://image.leyou.com/13123.jpg"));
  11. // 接收对象集合,实现批量新增
  12. itemRepository.saveAll(list);
  13. }

2.4、修改文档

修改文档数据也是使用的save()方法。

  1. @Autowired
  2. private ItemRepository itemRepository;
  3. @Test
  4. public void update(){
  5. //Optional是java8新添加的类
  6. Optional<Item> itemOptional= itemRepository.findById(1L);
  7. Item item = itemOptional.get();
  8. item.setTitle("修改后的小米8");
  9. itemRepository.save(item);
  10. }

2.5、基本简单查询


Spring Data Elasticsearch篇(3):ElasticsearchRepository文档操作 - 图2
【代码例子】

  1. /**
  2. * 查询全部,并安装价格降序排序
  3. */
  4. @Test
  5. public void testFind(){
  6. // Sort是包下的org.springframework.data类,Sort.Direction是个枚举类
  7. Iterable<Item> items = this.itemRepository.findAll(Sort.by(Sort.Direction.DESC, "price"));
  8. items.forEach(item-> System.err.println(item));
  9. }

2.6、自定义方法查询

我们在DAO层的ItemRepository接口中自定义按照价格区间查询方法:

  1. public interface ItemRepository extends ElasticsearchRepository<Item,Long> {
  2. /**
  3. * 方法名必须遵守SpringData的规范
  4. * 价格区间查询
  5. */
  6. List<Item> findByPriceBetween(double price1, double price2);
  7. }

【代码】

  1. @Autowired
  2. private ItemRepository itemRepository;
  3. /**
  4. * 自定义方法findByPriceBetween查询范围
  5. */
  6. @Test
  7. public void queryByPriceBetween(){
  8. List<Item> items = itemRepository.findByPriceBetween(3500, 4500);
  9. items.stream().forEach(item -> {
  10. System.err.println("item:"+item);
  11. });
  12. }