springboot集成ElasticSearch

简介:使用springboot2.0.2集成ElasticSearch5.5.1,ElasticSearch5.5.1后文统称es。

一、创建项目
在这里插入图片描述
在这里插入图片描述
完成的pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.sun.es</groupId>
    <artifactId>spring-boot-es</artifactId>
    <version>1.0-SNAPSHOT</version>


    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.2.RELEASE</version>
        <relativePath/>
    </parent>
    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--spring整合elasticsearch包-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>

        <!--实体工具包-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <!--集合工具包-->
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>19.0</version>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.6.1</version>
        </dependency>

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.6.1</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <executable>true</executable>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

配置es

spring:
  data:
    elasticsearch:
      cluster-name: my_es  #es 集群名字
      cluster-nodes: 192.168.1.104:9300,192.168.1.104:9301 #es集群节点

启动类加载 ElasticsearchRepository接口

@SpringBootApplication
@EnableElasticsearchRepositories(basePackages = "org.sun.es.dao") // 将es操作接口注入到spring容器
public class StartApp {

    public static void main(String[] args) {
        SpringApplication.run(StartApp.class,args);
    }

}

创建实体类

@Document(indexName = "poem",type = "poem",shards = 1, replicas = 0)
public class Poem {

    @Id
    private long id;
    private String title;
    private String content;

    public Poem(long id, String title, String content) {
        this.id = id;
        this.title = title;
        this.content = content;
    }

    public Poem(String title, String content) {
        this.title = title;
        this.content = content;
    }

    public Poem() {
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

创建es操作接口

public interface PoemRepository extends ElasticsearchRepository<Poem,Long>{
}

创建业务逻辑处理接口和实现类

接口
public interface PoemService {
   //保存Poem实体
   void save(Poem poem);

   //基于title和content进行搜索,返回分页
   Page<Poem> search(String title, String content, Pageable pageable);

   //基于content进行搜索,返回分页
   Page<Poem> search(String content, Pageable pageable);

   //返回所有数据集合
   Page<Poem> findAll(Pageable pageable);
}
实现类
@Service
public class PoemServiceImpl implements PoemService{

    // 被检索的列
    private static final String INDEX_TITLE = "title";
    private static final String INDEX_CONTENT = "content";

    @Autowired
    private PoemRepository poemRepository;

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;


    @Override
    public void save(Poem poem) {
        poemRepository.save(poem);
    }

    @Override
    public Page<Poem> search(String title, String content, Pageable pageable) {



        return poemRepository.findByTitleLikeOrContentLike(title,content,pageable);
    }

    /**
     * 查询:标题必须存在,内容可以不存在
     * @param query
     * @param pageable
     * @return 高亮结果集
     */
    @Override
    public Page<Poem> search(String query, Pageable pageable) {
        // 设置检索条件 matchQuery必须存在  multiMatchQuery可能存在  具体查看--->>>https://blog.csdn.net/lom9357bye/article/details/52852533
        QueryBuilder queryTitle = QueryBuilders.matchQuery(INDEX_TITLE, query);
        QueryBuilder queryContent = QueryBuilders.multiMatchQuery(query,INDEX_CONTENT);
        // BoolQueryBuilder用于组合查询 可以设置多条件  具体查看--->>>https://www.cnblogs.com/xiaocandou/p/8127371.html
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(queryTitle).should(queryContent);

        // 给指定列设置高亮标签
        HighlightBuilder.Field titleHighLight = new HighlightBuilder.Field(INDEX_TITLE);
        titleHighLight.preTags("<span style='color:red'>");
        titleHighLight.postTags("</span>");

        HighlightBuilder.Field contentHighLight = new HighlightBuilder.Field(INDEX_CONTENT);
        contentHighLight.preTags("<span style='color:red'>");
        contentHighLight.postTags("</span>");

        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(boolQueryBuilder) // 需要执行的es语句
                .withHighlightFields(
                        titleHighLight,
                        contentHighLight) // 设置高亮
                .withPageable(pageable) // 设置分页
                .build();

        // 使用springboot提供的类执行查询
        Page<Poem> poems = elasticsearchTemplate.queryForPage(searchQuery, Poem.class, new SearchResultMapper() {
            /**
             *
             * @param response 返回的结果
             * @param aClass 反射的javaBean
             * @param pageable 分页对象
             * @param <T> 返回泛型结果集
             * @return
             */
            @Override
            public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> aClass, Pageable pageable) {
                List<Poem> poems = new ArrayList<>();
                SearchHits hits = response.getHits();
                for (SearchHit hit : hits) {
                    if (hits.totalHits <= 0) {
                        return null;
                    }
                    Poem poem = new Poem();
                    poem.setId(Long.valueOf(hit.getId()));
                    poem.setTitle(String.valueOf(hit.getSource().get("title")));
                    poem.setContent(String.valueOf(hit.getSource().get("content")));

                    setHighLight(hit, "title", poem);
                    setHighLight(hit, "content", poem);

                    poems.add(poem);

                }
                return new AggregatedPageImpl<>((List<T>) poems);
            }
        });
        return poems;

    }

    @Override
    public Page<Poem> findAll(Pageable pageable) {
        return poemRepository.findAll(pageable);
    }




    /**
     * 设置高亮
     * @param hit 命中记录
     * @param filed 字段
     * @param object 待赋值对象
     */
    private static void setHighLight(SearchHit hit, String filed, Object object){
        //获取对应的高亮域
        Map<String, HighlightField> highlightFields = hit.getHighlightFields();
        HighlightField highlightField = highlightFields.get(filed);
        if (highlightField != null){
            //取得定义的高亮标签
            String highLightMessage = highlightField.fragments()[0].toString();
            // 反射调用set方法将高亮内容设置进去
            try {
                String setMethodName = parSetMethodName(filed);
                Class<?> Clazz = object.getClass();
                Method setMethod = Clazz.getMethod(setMethodName, String.class);
                setMethod.invoke(object, highLightMessage);
            } catch (Exception e) {
                System.out.println("反射报错");
            }
        }
    }

    /**
     * 根据字段名,获取Set方法名
     * @param fieldName 字段名
     * @return  Set方法名
     */
    private static String parSetMethodName(String fieldName){
        if (StringUtils.isBlank(fieldName)){
            return null;
        }
        int startIndex = 0;
        if (fieldName.charAt(0) == '_'){
            startIndex = 1;
        }
        return "set" + fieldName.substring(startIndex, startIndex + 1).toUpperCase()
                + fieldName.substring(startIndex + 1);
    }

}

创建controller

@Controller
public class WebController {
    @Autowired
    private PoemServiceImpl poemService;

    @Autowired
    PoemRepository poemRepository;

    
    @GetMapping("/")
    public String index(Model model) {
        List<Poem> poems = new ArrayList<>();
        poems.add(new Poem(4, "湘春夜月·近清明", "近清明,翠禽枝上消魂,可惜一片清歌,都付与黄昏。欲共柳花低诉,怕柳花轻薄,不解伤春。念楚乡旅宿,柔情别绪,谁与温存。"));
        poems.add(new Poem(5, "卜算子·不是爱风尘", "不是爱风尘,似被前缘误。花落花开自有时,总赖东君主。\n" +
                "去也终须去,住也如何住!若得山花插满头,莫问奴归处"));
        poems.add(new Poem(6, "御街行·秋日怀旧", "纷纷坠叶飘香砌。夜寂静,寒声碎。真珠帘卷玉楼空,天淡银河垂地。年年今夜,月华如练,长是人千里。"));

        for (int i = 0; i < poems.size(); i++) {
            poemService.save(poems.get(i));
        }
        model.addAttribute("poems", poems);

        return "/index";

    }


    
    @ApiImplicitParams({
            @ApiImplicitParam(name = "content", value = "输入的关键字", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "pageIndex", value = "当前页", required = true, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "每页显示条数", required = true, dataType = "int", paramType = "query")
    })
    @PostMapping("/search")
    public String search(String content, @RequestParam(value="pageIndex",required=false,defaultValue="0") int pageIndex,
                         @RequestParam(value="pageSize",required=false,defaultValue="10") int pageSize,Model model) {
                Pageable pageable = new PageRequest(pageIndex,pageSize);
                Page<Poem> poems = poemService.search(content,pageable);
                List<Poem> list = poems.getContent();
                model.addAttribute("poems",list);
                return "/list";
    }
}

启动项目
swagger查看api
es插入数据并回显到页面
在这里插入图片描述
根据标题搜索 - 近
在这里插入图片描述
至此,整合完毕
源码地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值