Spring Boot结合Jest实现对ElasticSearch的全文检索,分词检索,分页,高亮关键词,多字段检索

前提:本地已配置好es,我本地安装es为6.8.0,ik分词器也是6.8.0,这两个版本号必须一致的,以及es中已经存在数据

es下载地址:es下载,可以选版本
ik分词器下载地址:ik分词器下载,选取同样版本

数据格式及索引名称,可以es-head中看见

Spring Boot结合Jest实现对ElasticSearch的全文检索,分词检索,分页,高亮关键词,多字段检索_第1张图片
es-head中创建索引

{
	"mappings":{
		"downtype":{
			"properties":{
				"itemid":{
					"type":"long",
					"fields":{
						"keyword":{
							"type":"keyword"
							}
						}
					},
				"catid":{
					"type":"integer",
					"fields":{
						"keyword":{
							"type":"keyword"
						}
					}
				},
				"areaid":{
					"type":"integer",
					"fields":{
						"keyword":{
							"type":"keyword"
							}
					}
				},
				"title":{
					"type":"text",
					"analyzer":"ik_max_word",
					"fields":{
						"keyword":{
							"type":"keyword"
						}
					}
				},
				"keyword":{
					"type":"text",
					"analyzer":"ik_max_word",
					"fields":{
						"keyword":{
							"type":"keyword"
						}
					}
				}
			}
		}
	}
}
  1. 要检索的字段一定要在创建索引的时候带上"analyzer":“ik_max_word”,或者 ik_smart
    这是分词的关键,需要检索的字段的type值必须为keyword, 在上面 的索引源码中很清楚

项目结构:

Spring Boot结合Jest实现对ElasticSearch的全文检索,分词检索,分页,高亮关键词,多字段检索_第2张图片
接下来直接上源码

application.yml

server:
  port: 6325
spring:
  elasticsearch:

    jest:

      uris:

        - http://localhost:9200 # ES�������ĵ�ַ��

      read-timeout: 5000
debug: true

pom.xml

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.2.1.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>esdemo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>esdemo</name>
	<description>Demo project for Spring Boot</description>

	<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-data-elasticsearch</artifactId>
		</dependency>

		<dependency>
			<groupId>io.searchbox</groupId>
			<artifactId>jest</artifactId>
		</dependency>
		<dependency>
			<groupId>net.java.dev.jna</groupId>
			<artifactId>jna</artifactId>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
        <dependency>
            <groupId>com.vaadin.external.google</groupId>
            <artifactId>android-json</artifactId>
            <version>0.0.20131108.vaadin1</version>
            <scope>compile</scope>
        </dependency>
		<dependency>
			<groupId>net.sf.json-lib</groupId>
			<artifactId>json-lib</artifactId>
			<version>2.4</version>
			<classifier>jdk15</classifier>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.10.0</version>
		</dependency>
    </dependencies>

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

</project>

PageController

package com.example.esdemo.controller;



import com.example.esdemo.entity.Down;
import com.example.esdemo.service.PageService;
import net.sf.json.JSONArray;
import org.apache.commons.lang3.StringUtils;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;


import java.util.List;

@RestController

@RequestMapping("/pageController")
public class PageController {

    @Autowired
    PageService pageService;

    @Component
    public interface DownRepository extends ElasticsearchRepository<Down, Long> {
    }

    @RequestMapping(value="/search", method= RequestMethod.GET)
    public List<Down> save(String title) {
        List<Down> downList = null;
        if(StringUtils.isNotEmpty(title)) {
            downList = pageService.searchDown(title);

        }
        JSONArray jsonArray = JSONArray.fromObject(downList);
        System.out.println("查询结果:"+ jsonArray);
        //或者在postman中访问http://localhost:6325/downController/search?title=人民上海
        return downList;
    }
}

Down

package com.example.esdemo.entity;

import java.io.Serializable;


public class Down implements Serializable {

    private static final long serialVersionUID = -763638353551774166L;
    // 索引名称
    public static final String DOWN_NAME = "down";
    //索引类型
    public static final String TYPE = "downtype";


    private Long itemid;

    private Integer catid;

    private Integer areaid;

    private String title;

    private String keyword;

    public Down() {

        super();

    }

    public Down(Long itemid,Integer catid,Integer areaid,String title,String keyword) {

        this.itemid = itemid;

        this.catid = catid;
        this.areaid = areaid;
        this.title = title;
        this.keyword = keyword;


    }


    public Long getItemid() {
        return itemid;
    }

    public void setItemid(Long itemid) {
        this.itemid = itemid;
    }

    public Integer getCatid() {
        return catid;
    }

    public void setCatid(Integer catid) {
        this.catid = catid;
    }

    public Integer getAreaid() {
        return areaid;
    }

    public void setAreaid(Integer areaid) {
        this.areaid = areaid;
    }

    public String getTitle() {
        return title;
    }

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

    public String getKeyword() {
        return keyword;
    }

    public void setKeyword(String keyword) {
        this.keyword = keyword;
    }
}

PageServicelmpl

package com.example.esdemo.service.impl;

import com.example.esdemo.entity.Down;
import com.example.esdemo.service.PageService;

import io.searchbox.client.JestClient;
import io.searchbox.client.JestResult;
import io.searchbox.core.Search;
import io.searchbox.core.SearchResult;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;


import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;



import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


@Service
public class PageServicelmpl implements PageService {
    private static final Logger LOGGER = LoggerFactory.getLogger(TestServiceImpl.class);
    @Autowired
    private JestClient jestClient;



    @Override
    public List<Down> searchDown(String title) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //检索条件
        if (title != null) {
            boolQueryBuilder.should(QueryBuilders.commonTermsQuery("title",title));
            boolQueryBuilder.should(QueryBuilders.commonTermsQuery("keyword", title));

        }
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("title");//高亮title
        highlightBuilder.field("keyword");//高亮keyword
        highlightBuilder.preTags("").postTags("");//高亮样式
        //highlightBuilder.fragmentSize(20);//高亮长度

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.highlighter(highlightBuilder);
        //排序
        searchSourceBuilder.sort("itemid", SortOrder.ASC);
        //分页
        int page = 1;
        int size = 10;
        int index = (page - 1) * size;
//        searchSourceBuilder.from(index);
//        searchSourceBuilder.size(size);
//
        searchSourceBuilder.query(boolQueryBuilder).from(index);
        searchSourceBuilder.query(boolQueryBuilder).size(size); //需要检索的数据条数,这里可以设计为分页
        Search search = new Search.Builder(searchSourceBuilder.toString())
                .addIndex(Down.DOWN_NAME).addType(Down.TYPE).build();
        try {
            //TransformerClosure jestClient;
            JestResult result = jestClient.execute(search);
            System.out.println("本次查询共查到:"+ ((SearchResult) result).getTotal()+"条数据!");
            System.out.println("每页显示:"+ size+"条数据!");
            List<SearchResult.Hit<Down,Void>> hits = ((SearchResult) result).getHits(Down.class);

            List<Down> downList = new ArrayList<Down>();

            for (SearchResult.Hit<Down, Void> hit : hits) {
                Down source = hit.source;
                //获取高亮后的内容
                Map<String, List<String>> highlight = hit.highlight;
                if (highlight!=null){
                    List<String> titles = highlight.get("title");//高亮后的title
                    if(titles!=null){
                        source.setTitle(titles.get(0));
                    }
                    List<String> keyword = highlight.get("keyword");//高亮后的keyword
                    if(keyword!=null){
                        source.setKeyword(keyword.get(0));
                    }
                }
                Down down = new Down();
                //重新构建类
                down.setTitle(source.getTitle());
                down.setKeyword(source.getKeyword());
                down.setItemid(source.getItemid());
                down.setCatid(source.getCatid());
                down.setAreaid(source.getAreaid());

                downList.add(down);
            }
            return downList;
        } catch (IOException e) {
            LOGGER.error(e.getMessage());
            e.printStackTrace();
        }
        return null;
    }

}


PageService

package com.example.esdemo.service;


import com.example.esdemo.entity.Down;


import java.util.List;


public interface PageService {
    List<Down> searchDown(String title);

}

只要你本地es环境已经配好,代码直接复制过去就绝对可以运行起来

下面展示一下搜索结果
Spring Boot结合Jest实现对ElasticSearch的全文检索,分词检索,分页,高亮关键词,多字段检索_第3张图片
Spring Boot结合Jest实现对ElasticSearch的全文检索,分词检索,分页,高亮关键词,多字段检索_第4张图片

有问题的可以加我QQ:63211591来交流

你可能感兴趣的:(spring)