spring-data-elasticsearch + java 查询方法的封装

时间:2025-04-22 12:58:54
  • 最近开始重构elasicsearch+springboot+spring data elasticsearch的东西

  • 由于近期更新了elasticsearch /,大家都忙着尝鲜,不过其中整合框架的过程中遇到了很多的问题

  • 在复写项目的过程中,有重新温习了一下spring data elasticsearch 的操作,我当前尝试的是spring-data-elasticsearch 3.0.版本,比对以前的一些操作修改的不多,就是一些save=>saveAll,findOne=>findById,findAll=>findAllByIds等等,底层的操作原理没有影响,如果会的同志应当不会太困扰
  • 后期还会对transportClient的使用和框架整合ES的searchquery的介绍
以下是旧版本的spring-data-elasticsearch +java的操作:

1、封装数据库基本CRUD(创建(Create)、更新(Update)、读取(Retrieve)和删除(Delete))

public interface CrudRepository<T, ID extends Serializable>
 extends Repository<T, ID> {

 <S extends T> S save(S entity);

 T findOne(ID primaryKey);    

 Iterable<T> findAll();     

 Long count();          

 void delete(T entity);     

 boolean exists(ID primaryKey); 

 // … more functionality omitted.
}

2、分页排序查询

public interface PagingAndSortingRepository<T, ID extends Serializable>
 extends CrudRepository<T, ID> {

 Iterable<T> findAll(Sort sort);

 Page<T> findAll(Pageable pageable);
}

//Accessing the second page by a page size of 20
PagingAndSortingRepository<User, Long> repository = // … get access to a bean
Page<User> users = (new PageRequest(1, 20));

3、计数

public interface UserRepository extends CrudRepository<User, Long> {

 Long countByLastname(String lastname);
}

4、删除

public interface UserRepository extends CrudRepository<User, Long> {

 Long deleteByLastname(String lastname);

 List<User> removeByLastname(String lastname);

}

5、自定义查询方法自动注入
声明一个接口继承Repository

interface PersonRepository extends Repository<Person, Long> {
List<Person> findByLastname(String lastname);
}

保证注入了elasticsearch配置
在中写入了spring-data-elasticsearch的配置文件将自动注入
注入调用

public class SomeClient {

 @Autowired
 private PersonRepository repository;

 public void doSomething() {
  List<Person> persons = ("Matthews");
 }
}

6、支持Java8 Stream查询和sql语句查询

@Query("select u from User u")
Stream<User> findAllByCustomQueryAndStream();

Stream<User> readAllByFirstnameNotNull();

@Query("select u from User u")
Stream<User> streamAllPaged(Pageable pageable);

try (Stream<User> stream = ()) {
 (…);
}

7、支持异步查询

@Async
Future<User> findByFirstname(String firstname);        

@Async
CompletableFuture<User> findOneByFirstname(String firstname);

@Async
ListenableFuture<User> findOneByLastname(String lastname);

支持原生es JavaAPI

1、NativeSearchQueryBuilder构建查询

@Autowired
private ElasticsearchTemplate elasticsearchTemplate;

SearchQuery searchQuery = new NativeSearchQueryBuilder()
  .withQuery(matchAllQuery())
  .withFilter(boolFilter().must(termFilter("id", documentId)))
  .build();

Page<SampleEntity> sampleEntities =
  (searchQuery,);

2、利用Scan和Scroll进行大结果集查询

SearchQuery searchQuery = new NativeSearchQueryBuilder()
  .withQuery(matchAllQuery())
  .withIndices("test-index")
  .withTypes("test-type")
  .withPageable(new PageRequest(0,1))
  .build();
String scrollId = (searchQuery,1000,false);
List<SampleEntity> sampleEntities = new ArrayList<SampleEntity>();
boolean hasRecords = true;
while (hasRecords){
  Page<SampleEntity> page = (scrollId, 5000L , new ResultsMapper<SampleEntity>()
  {
    @Override
    public Page<SampleEntity> mapResults(SearchResponse response) {
      List<SampleEntity> chunk = new ArrayList<SampleEntity>();
      for(SearchHit searchHit : ()){
        if(().getHits().length <= 0) {
          return null;
        }
        SampleEntity user = new SampleEntity();
        (());
        ((String)().get("message"));
        (user);
      }
      return new PageImpl<SampleEntity>(chunk);
    }
  });
  if(page != null) {
    (());
    hasRecords = ();
  }
  else{
    hasRecords = false;
  }
  }
}

3、获取client实例进行节点操作,可以自行封装Util方法

@Autowired
private ElasticsearchTemplate elasticsearchTemplate;

public void searchHelper() throws IOException {

    //节点客户端
    // on startup
//    Node node = nodeBuilder().clusterName("syncwt-es").client(true).node();
//    Client nodeClient = ();

    //传输客户端
//    Settings settings = ().build();
//    Client transportClient = ().settings(settings).build();

    Client transportClient = ();

    Customer customer = new Customer("Alice", "Smith");

    // instance a json mapper
    ObjectMapper mapper = new ObjectMapper(); // create once, reuse

    // generate json
    String json = (customer);
    ("--------------------------------jackson mapper");
    (json);

    XContentBuilder builder = jsonBuilder()
        .startObject()
        .field("firstName", "Alice")
        .field("latName", "Smith")
        .endObject();
    ("--------------------------------jsonBuilder");
    (());

    IndexResponse response = ("es-customer", "customer")
        .setSource(jsonBuilder()
            .startObject()
            .field("firstName", "Alice")
            .field("latName", "Smith")
            .endObject()
        )
        .execute()
        .actionGet();

    ("--------------------------------response");
    (());

    // on shutdown
//    ();
//    ();
    ();

  }