当前位置:   article > 正文

Elastic Search搜索引擎在SpringBoot中的实践

springboot elasticsearch搜索框搜索总条数

Smartisan

注: 本文首发于 My 公众号 CodeSheep ,可 长按扫描 下面的 小心心 来订阅 ↓ ↓ ↓

CodeSheep · 程序羊


实验环境

  • ES版本:5.3.0
  • spring bt版本:1.5.9

首先当然需要安装好elastic search环境,最好再安装上可视化插件 elasticsearch-head来便于我们直观地查看数据。

当然这部分可以参考本人的帖子:
《centos7上elastic search安装填坑记》
https://www.jianshu.com/p/04f...

我的ES安装在http://113.209.119.170:9200/这个地址(该地址需要配到springboot项目中去)


Spring工程创建

这部分没有特殊要交代的,但有几个注意点一定要当心

  • 注意在新建项目时记得勾选web和NoSQL中的Elasticsearch依赖,来张图说明一下吧:

创建工程时勾选Nosql中的es依赖选项

项目自动生成以后pom.xml中会自动添加spring-boot-starter-data-elasticsearch的依赖:

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
  4. </dependency>
  • 本项目中我们使用开源的基于restful的es java客户端jest,所以还需要在pom.xml中添加jest依赖:
  1. <dependency>
  2. <groupId>io.searchbox</groupId>
  3. <artifactId>jest</artifactId>
  4. </dependency>
  • 除此之外还必须添加jna的依赖:
  1. <dependency>
  2. <groupId>net.java.dev.jna</groupId>
  3. <artifactId>jna</artifactId>
  4. </dependency>

否则启动spring项目的时候会报JNA not found. native methods will be disabled.的错误:

JNA not found. native methods will be disabled.

  • 项目的配置文件application.yml中需要把es服务器地址配置对
  1. server:
  2. port: 6325
  3. spring:
  4. elasticsearch:
  5. jest:
  6. uris:
  7. - http://113.209.119.170:9200 # ES服务器的地址!
  8. read-timeout: 5000

代码组织

我的项目代码组织如下:
项目代码组织

各部分代码详解如下,注释都有:

  • Entity.java
  1. package com.hansonwang99.springboot_es_demo.entity;
  2. import java.io.Serializable;
  3. import org.springframework.data.elasticsearch.annotations.Document;
  4. public class Entity implements Serializable{
  5. private static final long serialVersionUID = -763638353551774166L;
  6. public static final String INDEX_NAME = "index_entity";
  7. public static final String TYPE = "tstype";
  8. private Long id;
  9. private String name;
  10. public Entity() {
  11. super();
  12. }
  13. public Entity(Long id, String name) {
  14. this.id = id;
  15. this.name = name;
  16. }
  17. public Long getId() {
  18. return id;
  19. }
  20. public void setId(Long id) {
  21. this.id = id;
  22. }
  23. public String getName() {
  24. return name;
  25. }
  26. public void setName(String name) {
  27. this.name = name;
  28. }
  29. }
  • TestService.java
  1. package com.hansonwang99.springboot_es_demo.service;
  2. import com.hansonwang99.springboot_es_demo.entity.Entity;
  3. import java.util.List;
  4. public interface TestService {
  5. void saveEntity(Entity entity);
  6. void saveEntity(List<Entity> entityList);
  7. List<Entity> searchEntity(String searchContent);
  8. }
  • TestServiceImpl.java
  1. package com.hansonwang99.springboot_es_demo.service.impl;
  2. import java.io.IOException;
  3. import java.util.List;
  4. import com.hansonwang99.springboot_es_demo.entity.Entity;
  5. import com.hansonwang99.springboot_es_demo.service.TestService;
  6. import org.elasticsearch.index.query.QueryBuilders;
  7. import org.elasticsearch.search.builder.SearchSourceBuilder;
  8. import org.slf4j.Logger;
  9. import org.slf4j.LoggerFactory;
  10. import org.springframework.beans.factory.annotation.Autowired;
  11. import org.springframework.stereotype.Service;
  12. import io.searchbox.client.JestClient;
  13. import io.searchbox.client.JestResult;
  14. import io.searchbox.core.Bulk;
  15. import io.searchbox.core.Index;
  16. import io.searchbox.core.Search;
  17. @Service
  18. public class TestServiceImpl implements TestService {
  19. private static final Logger LOGGER = LoggerFactory.getLogger(TestServiceImpl.class);
  20. @Autowired
  21. private JestClient jestClient;
  22. @Override
  23. public void saveEntity(Entity entity) {
  24. Index index = new Index.Builder(entity).index(Entity.INDEX_NAME).type(Entity.TYPE).build();
  25. try {
  26. jestClient.execute(index);
  27. LOGGER.info("ES 插入完成");
  28. } catch (IOException e) {
  29. e.printStackTrace();
  30. LOGGER.error(e.getMessage());
  31. }
  32. }
  33. /**
  34. * 批量保存内容到ES
  35. */
  36. @Override
  37. public void saveEntity(List<Entity> entityList) {
  38. Bulk.Builder bulk = new Bulk.Builder();
  39. for(Entity entity : entityList) {
  40. Index index = new Index.Builder(entity).index(Entity.INDEX_NAME).type(Entity.TYPE).build();
  41. bulk.addAction(index);
  42. }
  43. try {
  44. jestClient.execute(bulk.build());
  45. LOGGER.info("ES 插入完成");
  46. } catch (IOException e) {
  47. e.printStackTrace();
  48. LOGGER.error(e.getMessage());
  49. }
  50. }
  51. /**
  52. * 在ES中搜索内容
  53. */
  54. @Override
  55. public List<Entity> searchEntity(String searchContent){
  56. SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  57. //searchSourceBuilder.query(QueryBuilders.queryStringQuery(searchContent));
  58. //searchSourceBuilder.field("name");
  59. searchSourceBuilder.query(QueryBuilders.matchQuery("name",searchContent));
  60. Search search = new Search.Builder(searchSourceBuilder.toString())
  61. .addIndex(Entity.INDEX_NAME).addType(Entity.TYPE).build();
  62. try {
  63. JestResult result = jestClient.execute(search);
  64. return result.getSourceAsObjectList(Entity.class);
  65. } catch (IOException e) {
  66. LOGGER.error(e.getMessage());
  67. e.printStackTrace();
  68. }
  69. return null;
  70. }
  71. }
  • EntityController.java
  1. package com.hansonwang99.springboot_es_demo.controller;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import com.hansonwang99.springboot_es_demo.entity.Entity;
  5. import com.hansonwang99.springboot_es_demo.service.TestService;
  6. import org.apache.commons.lang.StringUtils;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.web.bind.annotation.RequestMapping;
  9. import org.springframework.web.bind.annotation.RequestMethod;
  10. import org.springframework.web.bind.annotation.RestController;
  11. @RestController
  12. @RequestMapping("/entityController")
  13. public class EntityController {
  14. @Autowired
  15. TestService cityESService;
  16. @RequestMapping(value="/save", method=RequestMethod.GET)
  17. public String save(long id, String name) {
  18. System.out.println("save 接口");
  19. if(id>0 && StringUtils.isNotEmpty(name)) {
  20. Entity newEntity = new Entity(id,name);
  21. List<Entity> addList = new ArrayList<Entity>();
  22. addList.add(newEntity);
  23. cityESService.saveEntity(addList);
  24. return "OK";
  25. }else {
  26. return "Bad input value";
  27. }
  28. }
  29. @RequestMapping(value="/search", method=RequestMethod.GET)
  30. public List<Entity> save(String name) {
  31. List<Entity> entityList = null;
  32. if(StringUtils.isNotEmpty(name)) {
  33. entityList = cityESService.searchEntity(name);
  34. }
  35. return entityList;
  36. }
  37. }

实际实验

增加几条数据,可以使用postman工具,也可以直接在浏览器中输入,如增加以下5条数据:

  1. http://localhost:6325/entityController/save?id=1&name=南京中山陵
  2. http://localhost:6325/entityController/save?id=2&name=中国南京师范大学
  3. http://localhost:6325/entityController/save?id=3&name=南京夫子庙
  4. http://localhost:6325/entityController/save?id=4&name=杭州也非常不错
  5. http://localhost:6325/entityController/save?id=5&name=中国南边好像没有叫带京字的城市了

数据插入效果如下(使用可视化插件elasticsearch-head观看):
数据插入效果

我们来做一下搜索的测试:例如我要搜索关键字“南京”
我们在浏览器中输入:

http://localhost:6325/entityController/search?name=南京

搜索结果如下:

关键字“南京”的搜索结果

刚才插入的5条记录中包含关键字“南京”的四条记录均被搜索出来了!

当然这里用的是standard分词方式,将每个中文都作为了一个term,凡是包含“南”、“京”关键字的记录都被搜索了出来,只是评分不同而已,当然还有其他的一些分词方式,此时需要其他分词插件的支持,此处暂不涉及,后文中再做探索。


后记

作者更多的SpringBt实践文章在此:


如果有兴趣,也可以抽点时间看看作者一些关于容器化、微服务化方面的文章:


CodeSheep · 程序羊


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/543490
推荐阅读
相关标签
  

闽ICP备14008679号