SpringBoot学习系列(十六)------SpringBoot与检索
前言
全文检索技术也是目前在各个大型网站中使用比较多的,一般市面上都使用开源的ElasticSearche来实现,他基于Lucene,实现了RestfulAPI支持,使用起来也比较的方便,在本文中,我们将在SpringBoot中使用ElasticSearche.
正文
1. 在docker中下载ElasticSearche
因为在最近了解docker,所以在这里我们直接使用docker来运行elasticSearch,直接在Linux上运行下面的命令下载:
[root@localhost ~]# docker pull registry.docker-cn.com/library/elasticsearch
镜像拉取完成以后,我们就可以启动了,这里需要注意的是,ElasticSearche是用java开发的,在5.0以后,默认分配给jvm空间大小为2g,因此我在启动的时候会改变一下分配内存的大小,毕竟博主的服务器是阿里云的那种入门配置~~~~,直接运行下面命令即可:
# -e ES_JAVA_OPTS="-Xms256 -Xmx256"表示启动时使用jvm空间为256M
# 9200是elasticSearch的Web访问端口,9300是各节点之间的数据互通端口
[root@localhost ~]# docker run -e ES_JAVA_OPTS="-Xms256m -Xmx256m" -d -p 9200:9200 -p 9300:9300 --name myelasticsearch 镜像ID
启动以后,我们可以通过浏览器访问来查看是否启动正常:
出现这个页面说明ElasticSearch启动正常
2. ElasticSearch添加文档
在ElascticSearch中,每一条数据保存为一个文档,它有唯一的索引、类型,且包含属性,数据默认使用JSON来存储.
要向ES中添加文档很简单,我们只需要发送一个PUT请求,请求路径中包含文档的索引和类型,消息体中包含文档数据即可:
我们使用Postman来给我们的ES保存文档:
请求响应的数据如下:
3. ElasticSearch搜索文档、删除
在前面我们已经给ES中添加了文档,想要获取文档数据也是很简单的,在官方的文档说明中有具体的方法:
因为ES实现了Restful风格的API,所以要获得文档只需要发送get请求以及文档的位置即可,同样的,删除的话发送DELETE
请求.如果我们想判断某个文档是否存在,可以发送HEAD
请求,该请求是没有响应消息的,但是我们可以根据响应的状态码来判断该文档是否存在:状态码是200说明文档存在,状态码是404说明不存在
.
除了单个文档的增加和删除、更新,我们还可以直接查询所有的文档:
还有很多的条件查询的方式,可以参考官方文档来使用:ElasticSearch权威指南
4. SpringBoot整合ElasticSearch
创建一个SpringBoot工程,引入Web模块和ElasticSearch模块即可.
我们查看项目的pom文件发现,其实我们导入的是以下依赖:
<!--这里其实导入的是SpringData的组件,可见SpringBoot是使用SpringData来操作ES的-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
SpringBoot默认支持两种技术来和ES交互,我们查看SpringBoot的自动配置,可以发现导入了2中依赖:
这里需要注意,这两种包里面,上面的data包,是SpringData来提供对ES的支持,访问的是9300端口,而下面的jest,是一个基于HTTP的工具集,来操作ES,访问的是9200端口,就相当于我们在postman中发送HTTP请求一样调用ES数据.下面将分别来学习两种技术的使用
-
Jest操作ElasticSearch
首先我们在pom文件中引入jest,先注释掉ElasticSearch的依赖:
<!--<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency>--> <dependency> <groupId>io.searchbox</groupId> <artifactId>jest</artifactId> <version>5.3.3</version> </dependency>
我们查看
JestAutoConfiguration
可以看到,它帮我们自动注入一个JestClient
,要使用这个客户端,要先在配置文件中指定es的地址:#因为jest是用http请求来操作es的,所以要一个连接 spring.elasticsearch.jest.uris=http://ElasticSearch主机IP:9200
现在我们就可以直接在SpringBoot来使用Jest操作ES了
1.先来创建一个保存的javaBean
public class User { /** *使用jest保存文档,需要用注解指定id */ @JestId private int id; private String userName; private String passWord; //省略set/get }
2.使用jestClient操作ES
/** * 注入jest操作客户端 */ @Autowired private JestClient jestClient; /** * 使用jestClient增加索引 */ @Test public void addIndex() { //创建一个文档对象user User user = new User(); user.setId(1); user.setUserName("张三"); user.setPassWord("123456"); //使用ject保存文档,需要构建一个索引,使用Index的静态方法来构建 //构建的时候要传入数据对象,索引名以及类型 Index index = new Index.Builder(user).index("xiaojian").type("user").build(); //添加文档 try { jestClient.execute(index); } catch (IOException e) { e.printStackTrace(); } } /** * 获取文档 * 因为Jest使用的是HTTP的方式来操作ES的,所以我们要是用JSON格式的查询条件数据来获取 * 具体的获取可以参考Jest的文档来使用: * https://github.com/searchbox-io/Jest/tree/master/jest */ @Test public void getDocument() { //构架查询的表达式 String queryJson= "{\n" + " \"query\" : {\n" + " \"match\" : {\n" + " \"userName\" : \"张三\"\n" + " }\n" + " }\n" + "}"; //构建一个搜索文档的功能对象 //构建时要指定搜索的索引和类型 Search searchUser = new Search.Builder(queryJson) .addIndex("xiaojian") .addType("user").build(); //执行功能 try { SearchResult result = jestClient.execute(searchUser); //SearchResult对象是Jest中创建好的包含了搜索的所有信息的bean,需要的属性都在这个对象中 //这里我们直接打印这个查询结果对象 System.out.println(result.getJsonObject()); } catch (IOException e) { e.printStackTrace(); } }
查询到的结果如下:
{ "took":101, "timed_out":false, "_shards":{ "total":5, "successful":5, "skipped":0, "failed":0 }, "hits":{ "total":1, "max_score":0.51623213, "hits":[ { "_index":"xiaojian", "_type":"user", "_id":"1", "_score":0.51623213, "_source":{ "id":1, "userName":"张三", "passWord":"123456" } } ] } }
Jest的操作比较简单,我们可以很方便的通过它来操作ES,下面我们来看看使用SpringData的方式操作ES.
-
使用SpringBoot提供的支持操作ES
首先我们来看看ElasticSearch的自动配置类:
在这个包下的五个类,我们看一下源码就可以发现,SpringBoot默认帮我们自动装配了一下组件:
-
在
ElasticsearchAutoConfiguration
中,我们看到有个TransportClient
客户端,在创建这个客户端的时候,需要一个属性类:public class ElasticsearchProperties { private String clusterName = "elasticsearch"; private String clusterNodes;
也就是说,我们要在配置文件中配置这2个属性才能使用.
-
查看
ElasticsearchDataAutoConfiguration
,我们发现它帮我们配置了一个bean:@Bean @ConditionalOnMissingBean @ConditionalOnBean({Client.class}) public ElasticsearchTemplate elasticsearchTemplate(Client client, ElasticsearchConverter converter) { try { return new ElasticsearchTemplate(client, converter); } catch (Exception var4) { throw new IllegalStateException(var4); } }
有了SpringBoot以前的使用经验,我们知道这个Template可以用来操作ES,除了我们使用SpringBoot提供的Template来操作,我们也可以实现ElasticsearchRepository子接口的方式来操作,具体的详细内容可以参考官方文档来使用
https://github.com/spring-projects/spring-data-elasticsearch
,这里我们简单的使用即可. -
使用ElasticsearchRepository来增加和操作文档
首先我们在配置文件中指定ES的节点和名称:
spring.data.elasticsearch.cluster-nodes=服务器IP:9300/ spring.data.elasticsearch.cluster-name=elasticsearch #这里的cluster-name可以在浏览器访问:http://服务器IP:9200/来查看
定义一个javaBean用来创建文档数据:
/* *这里要用注解@Document来标注当前bean保存的索引名和类型 */ @Document(indexName = "xiaojian", type = "books") public class book { private Integer id; private String name; private double price;
我们来写一个接口继承ElasticsearchRepository:
public interface UserRepository extends ElasticsearchRepository<Book, Integer> { }
开始测试:
@Autowired private BookRepository bookRepository; @Test public void testRepository() { Book book = new Book(); book.setId(1); book.setName("java编程思想"); book.setPrice(100d); //保存文档 bookRepository.index(book); }
当然,我们也可以在repository中自定义方法:
public List<Book> findByBookNameLike(String bookName);
关于repository和rlasticSearchTemplate的更多使用,可以参照:官方文档
在使用的时候,也要注意版本的兼容问题,具体的版本使用可以参照文档中关于版本的说明
-
总结
关于ElasticSearch的使用就记录到这里,其实使用起来还是很简单的,参照官方的文档内容就可以实现复杂的功能实现.