当前位置:   article > 正文

springboot+elasticsearch实现全文检索_springboot es 全文检索

springboot es 全文检索

ElasticSearch 是一个分布式、可扩展、高性能的检索与数据分析引擎。ElasticSearch 基于 Java 编写,通过对Lucene进一步封装 ,将搜索的复杂性屏蔽起来,开发者只需要一套简单的 RESTful API 就可以操作全文检索。

1、windows环境es单节点安装
下载地址https://www.elastic.co/cn/downloads/past-releases/elasticsearch-7-9-3
下载后到指定目录解压即可,解压后的目录如下
在这里插入图片描述
进入bin目录,双击elasticsearch.bat启动即可。
在这里插入图片描述
看到started即启动成功。
默认监听的端口是9200,访问如下
在这里插入图片描述
浏览器安装插件,在chrome的app store中搜索Elasticsearch-head,点击安装即可。
在chrome 浏览器中,通过“扩展程序” 添加 elasticsearch head 插件的方式,这种方式无须开启 es的跨域访问,并提供了一个可操作es的图形化界面。
打开连接http://extb.cqttech.com/search/elasticsearch%2520head,点击安装,如下
在这里插入图片描述
访问的可视化界面如下
在这里插入图片描述
2、windows环境kibana安装
Kibana 是一个 Elastic 公司推出的一个针对 es 的分析及数据可视化平台,可以搜索、查看存放在 es 中的数据。

  • 下载地址:https://www.elastic.co/cn/downloads/kibana
  • 解压
  • 配置 es 的地址信息:若 es 是默认地址以及端口,可以不用配置,具体的配置文件是config/kibana.yml
  • 启动:双击kibana.bat即可
  • 访问localhost:5601
    界面如下
    在这里插入图片描述
    在这里插入图片描述
    Kibana 安装好之后,首次打开时,可以选择初始化 es 提供的测试数据,也可以不使用。

3、分词器
ElasticSearch 中内置了多种分词器,如Standard Analyzer:标准分词器,适用于英语等;其中中文分词器通常使用elasticsearch-analysis-ik,这个是第三方插件,下载地址如下:https://github.com/medcl/elasticsearch-analysis-ik/releases/tag/v7.9.3
下载后在es的plugins目录下,新建ik目录,并将解压后的所有文件拷贝到ik目录下,重启es服务。
注:es和kibana的安装路径不能有空格,否则启动会报错。
es重启成功后,首先创建一个名为test的索引(相当于是创建一个名为test的数据库),如下
在这里插入图片描述
在test索引中进行分词测试,如下
在这里插入图片描述
4、新建文档
创建索引后,向索引中添加一个文档,如下
在这里插入图片描述

  • _index表示文档索引
  • _type表示文档类型
  • _id表示文档id
  • _version表示文档版本
  • result表示执行的结果
  • _shards表示分片信息
  • _seq_no和_primary_term表示是版本控制用的
    添加文档成功后,通过浏览器插件可以看到如下
    在这里插入图片描述
    5、获取文档
    es中提供了GET API来查看es中的文档,如下
    在这里插入图片描述
    若获取的文档不存在,会返回如下
    在这里插入图片描述
    更新整个文档,如下
    在这里插入图片描述
    6、搜索
    创建索引,如下
    在这里插入图片描述
    查询文档,如下
    在这里插入图片描述
    添加文档
    在这里插入图片描述
    查询文档
    在这里插入图片描述
    或简单查询
    在这里插入图片描述
    词项查询,根据词去查询,查询指定字段中包含给定单词的文档,如下
    在这里插入图片描述
    7、全文检索
    在这里插入图片描述
    match query 会对查询语句进行分词,分此后如果查询语句中的任何一个词项被匹配,则文档就会被索引到。
    全文检索还有 match_phrase query、multi_match query、query_string query等,还有各种复杂的组合查询等,还需不断的尝试理解。

8、实例
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 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.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.ldc</groupId>
    <artifactId>springboot_elasticsearch</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot_elasticsearch</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-data-elasticsearch</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59

application.properties文件

elasticsearch.host=127.0.0.1
elasticsearch.port=9200
  • 1
  • 2

es配置类

@Configuration
@Data
public class ElasticsearchConfig extends AbstractElasticsearchConfiguration {

    @Value("${elasticsearch.host}")
    private String host ;
    @Value("${elasticsearch.port}")
    private Integer port ;

    @Override
    public RestHighLevelClient elasticsearchClient() {
        RestClientBuilder builder = RestClient.builder(new HttpHost(host, port));
        RestHighLevelClient restHighLevelClient = new RestHighLevelClient(builder);
        return restHighLevelClient;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

索引库实体类

@Data
@Document(indexName = "blog_index", type = "blog")
public class EsBlog {

    @Id
    private int id;

    /**
     * 是否索引: 看该域是否能被搜索, index = true(默认为true)
     * 是否分词: 表示搜索的时候是整体匹配还是单词匹配
     * 是否存储: 是否在页面上显示
     */
    @Field(type = FieldType.Text, analyzer = "ik_smart", searchAnalyzer = "ik_smart")
    private String title;

    @Field(type = FieldType.Text, analyzer = "ik_smart", searchAnalyzer = "ik_smart")
    private String content;

    public EsBlog() {
    }

    public EsBlog(int id, String title, String content) {
        this.id = id;
        this.title = title;
        this.content = content;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

es持久化

@Repository
public interface EsBlogRepository extends ElasticsearchRepository<EsBlog, Integer> {
    /**
     * 根据title或者内容分页查询
     *
     * @param title   标题
     * @param content 内容
     * @param page    分页
     * @return
     */
    Page<EsBlog> findByTitleOrContentLike(String title, String content, Pageable page);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

es服务

@Service
public class EsBlogServiceImpl implements EsBlogService {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Resource
    private EsBlogRepository esBlogRepository;

    @Resource
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    @Override
    public void save(EsBlog blog) {
        esBlogRepository.save(blog);
        logger.debug("save ok");
    }
    @Override
    public void save(List<EsBlog> blogs) {
        esBlogRepository.saveAll(blogs);
        logger.debug("save ok");
    }

    @Override
    public void delete(int id) {
        esBlogRepository.deleteById(id);
    }

    @Override
    public EsBlog getById(int id) {
        EsBlog esBlog = esBlogRepository.findById(id).orElse(new EsBlog());
        logger.debug(esBlog.toString());
        return esBlog;

    }

    @Override
    public Page<EsBlog> getByKey(String key, Pageable pageable) {
        if(StringUtils.isEmpty(key)){
            return esBlogRepository.findAll(pageable);
        }
        return esBlogRepository.findByTitleOrContentLike(key, key, pageable);
    }

    @Override
    public Page<EsBlog> getByKeyWord(String key, Pageable pageable) {
        if(StringUtils.isEmpty(key)){
            System.out.println("key is null");
        }
        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(matchQuery("title", key))
                .withQuery(matchQuery("content", key))
                .withPageable(pageable)
                .build();
        Page<EsBlog> esBlogs = elasticsearchRestTemplate.queryForPage(searchQuery, EsBlog.class);
        esBlogs.forEach(e -> logger.debug(e.toString()));
        return esBlogs;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

es接口

@RestController
@RequestMapping("blog")
public class EsBlogController {

    @Resource
    private EsBlogService searchService;

    @GetMapping("init")
    private String initBlog() {
        List<Blog> blogs = new ArrayList<>();
        blogs.add(new Blog(1, "java", "java编程语言"));
        blogs.add(new Blog(2, "netty", "netty编程"));
        List<EsBlog> esBlogs = new ArrayList<>();
        blogs.forEach(blog -> {esBlogs.add(new EsBlog(blog.getId(), blog.getTitle(), blog.getContent()));});
        searchService.save(esBlogs);
        return "init Success";
    }

    /**
     * @param blog 博客文档
     * @return
     */
    @PostMapping("save")
    public void save(EsBlog blog) {
        searchService.save(blog);
    }

    /**
     * @param id 文档id
     * @return
     */
    @GetMapping("getById")
    public Object getById(int id) {
        return searchService.getById(id);
    }

    /**
     * @param key 关键字
     * @return
     */
    @GetMapping("getByKey")
    public Page<EsBlog> getByKey(HttpServletRequest request, String key) {
        Pageable pageable = getPageByRequest(request);
        return searchService.getByKey(key, pageable);
    }

    /**
     * @param key 关键字
     * @return
     */
    @GetMapping("getByKeyWord")
    public Page<EsBlog> getByKeyWord(HttpServletRequest request, String key) {
        Pageable pageable = getPageByRequest(request);
        return searchService.getByKeyWord(key, pageable);
    }

    private Pageable getPageByRequest(HttpServletRequest request) {
        int page = StringUtils.isEmpty(request.getParameter("page")) ? 1 : Integer.parseInt(request.getParameter("page"));
        int size = StringUtils.isEmpty(request.getParameter("size")) ? 10 : Integer.parseInt(request.getParameter("size"));
        Pageable pageable = PageRequest.of(page - 1, size);
        return pageable;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63

检索示例如下
在这里插入图片描述
在这里插入图片描述

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

闽ICP备14008679号