如下所示文档举例说明了如何使用ElasticsearchOperations(默认实现是ElasticsearchTemplate ):
【1】Spring Data Elasticsearch
① 添加Elasticsearch-starter
pom文件添加starter如下:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency>
SpringBoot默认支持两种技术和Elasticsearch进行交互:Spring Data Elasticsearch
和Jest
。
Jest默认不生效,需要导入io.searchbox.client.JestClient
。
maven依赖如下:
<!--导入jest依赖--> <dependency> <groupId>io.searchbox</groupId> <artifactId>jest</artifactId> <version>5.3.3</version> </dependency>
② ElasticsearchAutoConfiguration中注册了client,属性有clusterNodes和clusterName。
③ ElasticsearchDataAutoConfiguration注册了ElasticsearchTemplate来操作ES
@Configuration @ConditionalOnClass({ Client.class, ElasticsearchTemplate.class }) @AutoConfigureAfter(ElasticsearchAutoConfiguration.class) public class ElasticsearchDataAutoConfiguration { @Bean @ConditionalOnMissingBean @ConditionalOnBean(Client.class) public ElasticsearchTemplate elasticsearchTemplate(Client client, ElasticsearchConverter converter) { try { return new ElasticsearchTemplate(client, converter); } catch (Exception ex) { throw new IllegalStateException(ex); } } @Bean @ConditionalOnMissingBean public ElasticsearchConverter elasticsearchConverter( SimpleElasticsearchMappingContext mappingContext) { return new MappingElasticsearchConverter(mappingContext); } @Bean @ConditionalOnMissingBean public SimpleElasticsearchMappingContext mappingContext() { return new SimpleElasticsearchMappingContext(); } }
④ ElasticsearchRepositoriesAutoConfiguration 启用了ElasticsearchRepository
@Configuration @ConditionalOnClass({ Client.class, ElasticsearchRepository.class }) @ConditionalOnProperty(prefix = "spring.data.elasticsearch.repositories", name = "enabled", havingValue = "true", matchIfMissing = true) @ConditionalOnMissingBean(ElasticsearchRepositoryFactoryBean.class) @Import(ElasticsearchRepositoriesRegistrar.class) public class ElasticsearchRepositoriesAutoConfiguration { }
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(); }
【2】JestClient操作测试
① application.properties配置
# jest url配置 spring.elasticsearch.jest.uris=http://192.168.2.110:9200
② 测试类
@RunWith(SpringRunner.class) @SpringBootTest public class SpringBootJestTest { @Autowired JestClient jestClient; @Test public void index(){ Article article = new Article(); article.setId(1); article.setAuthor("Tom"); article.setContent("hello world !"); article.setTitle("今日消息"); //构建一个索引功能,类型为news Index index = new Index.Builder(article).index("jest").type("news").build(); try { jestClient.execute(index); System.out.println("数据索引成功!"); } catch (IOException e) { e.printStackTrace(); } } @Test public void search(){ //查询表达式 String json = "{\n" + " \"query\" : {\n" + " \"match\" : {\n" + " \"content\" : \"hello\"\n" + " }\n" + " }\n" + "}"; //构建搜索功能 Search search = new Search.Builder(json).addIndex("jest").addType("news").build(); try { SearchResult result = jestClient.execute(search); System.out.println(result.getJsonString()); } catch (IOException e) { e.printStackTrace(); } } }
③ 测试存储数据结果
④ 测试查询数据结果
【3】 Elasticsearch版本调整
① application.properties进行配置
# Spring data elasticsearch配置 spring.data.elasticsearch.cluster-name=elasticsearch spring.data.elasticsearch.cluster-nodes=192.168.2.110:9300
这里节点名取自如下图:
启动主程序,可能报错如下(ES版本不合适):
查看Spring Data官网,其中spring data elasticsearch与elasticsearch适配表如下:
我们在上篇博文中安装的ES版本为5.6.10,项目中SpringBoot版本为1.5.12,spring-boot-starter-data-elasticsearch为2.1.11,elasticsearch版本为2.4.6。
两种解决办法:① 升级SpringBoot版本;② 安装2.4.6版本的elasticsearch。
这里修改暴露的端口,重新使用docker安装2.4.6版本:
# 拉取2.4.6 镜像 docker pull registry.docker-cn.com/library/elasticsearch:2.4.6 # 启动容器 docker run -e ES_JAVA_OPTS="-Xms256m -Xmx256m" -d -p 9201:9200 -p 9301:9300 --name ES02 bc337c8e4f
application.properties配置文件同步修改:
# jest url配置 spring.elasticsearch.jest.uris=http://192.168.2.110:9201 # Spring data elasticsearch配置 spring.data.elasticsearch.cluster-name=elasticsearch spring.data.elasticsearch.cluster-nodes=192.168.2.110:9301
此时再次启动程序:
【4】ElasticsearchRepository使用
我们这里以BookRepository 为例说明。
① BookRepository
类似于JPA,编写自定义Repository接口,继承自ElasticsearchRepository:
public interface BookRepository extends ElasticsearchRepository<Book,Integer> { public List<Book> findByBookNameLike(String bookName); }
这里第一个参数为对象类型,第二个参数为对象的主键类型。
BookRepository 所拥有的方法如下图:
② Book实体
// 这里注意注解 @Document(indexName = "elastic",type = "book") public class Book { private Integer id; private String bookName; private String author; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getBookName() { return bookName; } public void setBookName(String bookName) { this.bookName = bookName; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } @Override public String toString() { return "Book{" + "id=" + id + ", bookName='" + bookName + '\'' + ", author='" + author + '\'' + '}'; } }
③ 测试保存
@Autowired BookRepository bookRepository; @Test public void testRepository(){ Book book = new Book(); book.setAuthor("吴承恩"); book.setBookName("西游记"); book.setId(1); bookRepository.index(book); System.out.println("BookRepository 存入数据成功!"); }
测试结果
④ 测试查询
@Test public void testRepository2(){ for (Book book : bookRepository.findByBookNameLike("游")) { System.out.println("获取的book : "+book); } ; Book book = bookRepository.findOne(1); System.out.println("根据id查询 : "+book); }
测试结果
⑤ Elasticsearch支持方法关键字图示
即,在BookRepository中使用上述关键字构造方法,即可使用,Elastic自行实现其功能!
⑥ 支持@Query注解
如下所示,直接在方法上使用注解:
public interface BookRepository extends ElasticsearchRepository<Book, String> { @Query("{"bool" : {"must" : {"field" : {"name" : "?0"}}}}") Page<Book> findByName(String name,Pageable pageable); }
【5】ElasticsearchTemplate使用
封装的就是High Level REST Client,这是基于HTTP协议的客户端,是ES官方推荐使用的。但是要求对ES的DSL语句熟悉,方便自己做复杂的增删改查。
① 存入数据
@Autowired ElasticsearchTemplate elasticsearchTemplate; @Test public void testTemplate01(){ Book book = new Book(); book.setAuthor("曹雪芹"); book.setBookName("红楼梦"); book.setId(2); IndexQuery indexQuery = new IndexQueryBuilder().withId(String.valueOf(book.getId())).withObject(book).build(); elasticsearchTemplate.index(indexQuery); }
测试结果如下:
② 查询数据
@Test public void testTemplate02(){ QueryStringQueryBuilder stringQueryBuilder = new QueryStringQueryBuilder("楼"); stringQueryBuilder.field("bookName"); SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(stringQueryBuilder).build(); Page<Book> books = elasticsearchTemplate.queryForPage(searchQuery,Book.class); Iterator<Book> iterator = books.iterator(); while(iterator.hasNext()){ Book book = iterator.next(); System.out.println("该次获取的book:"+book); } }
测试结果如下: