Elasticsearch是构建在Apache Lucene上的使用Java语言开发的开源分布式搜素引擎。Lucene是一个开源的全文搜索引擎工具包,它仅是一个工具包而不是一个完整的工作引擎,并且只能被Java应用程序调用,elasticsearch基于REST API,因此任何开发语言开发的任何应用程序都可以通过JSON格式的HTTP请求来管理elasticsearch集群。elasticsearch封装并扩展了Luncene,使存储、索引、搜索都变得更快、更容易。除此之外,elasticsearch还可以完好地存储数据,甚至可以将其直接作为带搜索功能的NoSQL数据库来使用,它的数据是通过文档形式表示的。以下将elasticsearch都简称为es。
一、Docker安装Es单机版
-
创建外部文件挂载目录并授权
mkdir -p /data/elasticsearch/data mkdir -p /data/elasticsearch/config mkdir -p /data/elasticsearch/plugins chmod 777 /data/elasticsearch/data chmod 777 /data/elasticsearch/config chmod 777 /data/elasticsearch/plugins
-
创建配置文件
cd /data/elasticsearch/config touch elasticsearch.yml vim elasticsearch.yml
elasticsearch.yml文件内容
# ======================== Elasticsearch Configuration ========================= cluster.name: "docker-cluster" network.host: 0.0.0.0 http.cors.enabled: true http.cors.allow-origin: "*" http.cors.allow-headers: Authorization # true为开启鉴权,false关闭 xpack.security.enabled: false xpack.security.transport.ssl.enabled: true
-
创建Docker网卡
docker network create es-net
-
启动Es容器
docker run --restart=always \ --name es \ -p 9200:9200 -p 9300:9300 \ -e "discovery.type=single-node" \ -e ES_JAVA_OPTS="-Xms512m -Xmx512m" \ --privileged \ --network es-net \ -v /data/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \ -v /data/elasticsearch/data:/usr/share/elasticsearch/data \ -v /data/elasticsearch/plugins:/usr/share/elasticsearch/plugins \ -d elasticsearch:7.7.0
-
查看启动状态
docker ps
启动成功
二、浏览器安装Es-Head插件
- chrome应用商店 搜索Multi Elasticsearch Head插件并安装
- 启动插件,连接已安装的Es
- 成功后如图
三、代码演示
-
pom文件引入spring-boot-starter-data-elasticsearch依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency>
-
domain层数据传输对象
@Data @Document(indexName = "student") public class Student { @Id @ApiModelProperty(value = "id") private String id; @ApiModelProperty(value = "用户名") private String username; @ApiModelProperty(value = "密码") private String password; }
这里简单说一下,@Document注解即为指定索引名称,与Mybatis的@TableName有异曲同工之处,@Id指定主键,与MySQL的主键同理。
-
持久层Repository
@Repository public interface StudentRepository extends ElasticsearchRepository<Student, String> { /** * 根据用户名称模糊查询 * * @param userName 用户名称 * @return 学生列表 */ List<Student> findStudentByUsernameLike(String userName); /** * 根据排序区间查询学生列表 * * @param min 最小值 * @param max 最大值 * @return 学生列表 */ List<Student> findStudentBySortBetween(Integer min, Integer max); /** * 统计用户数量,根据用户名称模糊 * * @param userName 用户名称 * @return 用户数量 */ long countStudentByUsernameLike(String userName); }
这里简单举了几个查询的列子,例如主键查询、模糊查询、区间查询、统计数量等;可以看出来,与JPA的查询写法相同,输入查询条件即可。
-
服务层Service
@Service public class EsTestService { @Resource private StudentRepository studentRepository; public void addStudent(Student student) { studentRepository.save(student); } public void updateStudent(Student student) { if (StringUtils.isBlank(student.getId())) { throw new BadRequestAlertException(""); } Optional<Student> studentOptional = studentRepository.findById(student.getId()); if (!studentOptional.isPresent()) { throw new BadRequestAlertException(""); } Student realStudent = studentOptional.get(); BeanUtil.copyProperties(student, realStudent, CopyOptions.create().setIgnoreNullValue(true)); studentRepository.save(realStudent); } public List<Student> getStudentList(String userName) { List<Student> studentList; if (StringUtils.isNotBlank(userName)) { studentList = studentRepository.findStudentByUsernameLike(userName); } else { studentList = (List<Student>) studentRepository.findAll(); } return studentList; } public List<Student> getStudentListBySort(Integer min, Integer max) { List<Student> studentList; if (ObjectUtils.isNotEmpty(min) && ObjectUtils.isNotEmpty(max)) { studentList = studentRepository.findStudentBySortBetween(min, max); } else { studentList = (List<Student>) studentRepository.findAll(); } return studentList; } public Long countStudent(String userName) { long count; if (StringUtils.isNotBlank(userName)) { count = studentRepository.countStudentByUsernameLike(userName); } else { count = 0L; } return count; } public void deleteStudent(String id) { studentRepository.deleteById(id); } }
-
控制器
@RestController @RequestMapping("/api/user/es") @Api(tags = "ES测试") public class EsTestController { @Resource private EsTestService esTestService; @PostMapping("/add") @ApiOperation(value = "新增") public ResultEntity<Void> add(@RequestBody Student student) { esTestService.addStudent(student); return ResultEntity.success(); } @PostMapping("/update") @ApiOperation(value = "修改") public ResultEntity<Void> update(@RequestBody Student student) { esTestService.updateStudent(student); return ResultEntity.success(); } @GetMapping("/list") @ApiOperation(value = "查看列表") public ResultEntity<List<Student>> list(@RequestParam("userName") String userName) { return ResultEntity.success(esTestService.getStudentList(userName)); } @GetMapping("/list/sort") @ApiOperation(value = "排序区间查看列表") public ResultEntity<List<Student>> listBySort(@RequestParam("min") Integer min, @RequestParam("max") Integer max) { return ResultEntity.success(esTestService.getStudentListBySort(min, max)); } @GetMapping("/count") @ApiOperation(value = "统计") public ResultEntity<Long> count(@RequestParam("userName") String userName) { return ResultEntity.success(esTestService.countStudent(userName)); } @PostMapping("/delete") @ApiOperation(value = "删除") public ResultEntity<Void> delete(@RequestParam("id") String id) { esTestService.deleteStudent(id); return ResultEntity.success(); } }
四、测试
- 测试新增接口
刷新Es-Head查看数据是否新增成功
- 测试修改
- 多添加几个数据,查看列表
- 测试排序区间查询
- 测试统计接口
- 测试删除接口
删除前
删除后
五、总结
本文讲解了从安装ES、ES-Head插件开始,用SpringBoot框架集成Elasticsearch数据库的简单实例,ES是一个支持倒排索引的非关系型数据,其他还有很多好玩的地方,有兴趣可以自己试试。
所有你想象的一切,皆是现实!