Springboot基于ElasticSearch全文搜索引擎策略实现

10 篇文章 0 订阅
5 篇文章 0 订阅

一、ElasticSearch概念简介

ElasticSearch是一个基于Lucene的开源搜索引擎,具有分布式、多租户能力的全文搜索引擎。ElasticSearch的设计目标是实现分布式、可扩展和速度快的搜索架构,使得用户在数据量较大的情况下依然能够快速高效地对数据进行搜索和分析。

ElasticSearch使用RESTful API进行操作,支持结构化、非结构化数据的索引和搜索,适合用来解决大量数据的全文搜索、数据分析、日志查询等问题。

二、ElasticSearch基本理论

  • 文档(Document):Documents是ElasticSearch中的最小数据单元类似我们关系数据库的一条记录,一个文档由JSON格式数据构成。Index 里面单条的记录称为 Document(文档)。许多条 Document 构成了一个 Index。Document 使用 JSON 格式表示,下面是一个例子。


{
  "user": "张三",
  "title": "工程师",
  "desc": "数据库管理"
}
  • 索引(Index):Indexes类似于关系数据库中的数据库,每个索引包含多个类型和文档。ElasticSearch通过索引词典提高搜索效率。Elastic 会索引所有字段,经过处理后写入一个反向索引(Inverted Index)。查找数据的时候,直接查找该索引。所以,Elastic 数据管理的顶层单位就叫做 Index(索引)。它是单个数据库的同义词。每个 Index (即数据库)的名字必须是小写。

--下面的命令可以查看当前节点的所有 Index。
curl -X GET 'http://localhost:9200/_cat/indices?v'
  • 分片(Shard)与副本(Replica):Index可以分为多个Shards,并且每个Shard可以有多个Replicas。分片提高了并行搜索和存储的能力,而副本提供了高可用性。

  • 倒排索引:ElasticSearch使用倒排索引数据结构来实现快速的全文搜索。倒排索引将一个单词映射到包含这个单词的文档,从而加速搜索查询。

三、ElasticSearch应用场景

  1. 全文搜索:ElasticSearch可以用于网站、文档系统中的全文搜索功能。

  2. 日志分析:与Logstash和Kibana组合成ELK Stack,可以构建日志收集和分析系统。

  3. 大数据分析:利用其强大的聚合功能和分布式计算能力进行实时数据分析。

  4. 推荐系统:通过搜索引擎相关性计算和评分功能,实现个性化推荐系统。

四、ElasticSearch在Linux环境下的安装部署

Elastic 需要 Java 8 环境。如果你的机器还没安装 Java,以下是在Linux系统(以Ubuntu为例)中安装ElasticSearch的步骤:

1.安装Java环境 ElasticSearch要求安装Java 8或以上版本。

sudo apt update
sudo apt install openjdk-11-jdk

2.下载并安装ElasticSearch

wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.10.0-amd64.deb

sudo dpkg -i elasticsearch-7.10.0-amd64.deb

3.启动并设置ElasticSearch为开机自启动

sudo systemctl start elasticsearch

sudo systemctl enable elasticsearch

4.验证安装

curl -X GET "localhost:9200/"

会返回以下信息


{
  "name" : "atntrTf",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "tf9250XhQ6ee4h7YI11anA",
  "version" : {
    "number" : "7.10.0",
    "build_hash" : "19c13d0",
    "build_date" : "2022-07-18T20:44:24.823Z",
    "build_snapshot" : false,
    "lucene_version" : "6.6.0"
  },
  "tagline" : "You Know, for Search"
}

5.中文词搜索设置

首先,安装中文分词插件。这里使用的是 ik,也可以考虑其他插件(比如 smartcn)。

插件的下载地址:GitHub - infinilabs/analysis-ik: 🚌 The IK Analysis plugin integrates Lucene IK analyzer into Elasticsearch and OpenSearch, support customized dictionary.

./bin/elasticsearch-plugin install https://get.infini.cloud/elasticsearch/analysis-ik/8.4.1

上面代码安装的是8.4.1版的插件,与 Elastic 7.x及以上的版本 配合使用,具体细节查看插件的版本库文档教程。

接着,重新启动 Elastic,就会自动加载这个新安装的插件。

然后,新建一个 Index,指定需要分词的字段。这一步根据数据结构而异,下面的命令只针对本文。基本上,凡是需要搜索的中文字段,都要单独设置一下。

curl -X PUT 'localhost:9200/accounts' -d '
{
  "mappings": {
    "person": {
      "properties": {
        "user": {
          "type": "text",
          "analyzer": "ik_max_word",
          "search_analyzer": "ik_max_word"
        },
        "title": {
          "type": "text",
          "analyzer": "ik_max_word",
          "search_analyzer": "ik_max_word"
        },
        "desc": {
          "type": "text",
          "analyzer": "ik_max_word",
          "search_analyzer": "ik_max_word"
        }
      }
    }
  }
}'

上面代码中,首先新建一个名称为accounts的 Index,里面有一个名称为person的 Type。person有三个字段。

这三个字段都是中文,而且类型都是文本(text),所以需要指定中文分词器,不能使用默认的英文分词器。Elastic 的分词器称为 analyzer。我们对每个字段指定分词器。

上面代码中,analyzer是字段文本的分词器,search_analyzer是搜索词的分词器。ik_max_word分词器是插件ik提供的,可以对文本进行最大数量的分词。

五、ElasticSearch与Spring Boot 2的整合

1、核心依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    <version>${spring-boot.version}</version>
</dependency>

2、yml配置文件

spring:
  application:
    name: ware-elastic-search
  data:
    elasticsearch:
      # 默认 elasticsearch
      cluster-name: elasticsearch
      # 9200作为Http协议,主要用于外部通讯
      # 9300作为Tcp协议,jar之间就是通过tcp协议通讯
      cluster-nodes: 10.98.3.22:9300

3、实体类配置

Document配置,加上了@Document注解之后,默认情况下这个实体中所有的属性都会被建立索引、并且分词。

indexName索引名称 理解为数据库名 限定小写
type 理解为数据库的表名称
shards = 5 默认分区数
replicas = 1 每个分区默认的备份数
refreshInterval = "1s" 刷新间隔
indexStoreType = "fs"  索引文件存储类型

Java代码

import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;

@Document(indexName = "systemlogindex",type = "systemlog")
public class SystemLog {
    //Id注解Elasticsearch里相应于该列就是主键,查询时可以使用主键查询
    @Id
    private Long id;
    private String orderNo;
    private String userId;
    private String userName;
    private String logData;
    private String createTime;
}

实现ElasticsearchRepository接口。

public interface SystemLogRepository 
extends ElasticsearchRepository<SystemLog,Long> {
}

4.演示实例实现

@Service
public class SystemLogServiceImpl implements SystemLogService {
    @Resource
    private SystemLogRepository systemLogRepository ;
    @Override
    public String esInsert(Integer num) {
        for (int i = 0 ; i < num ; i++){
            SystemLog systemLog= new SystemLog() ;
            systemLog.setId(System.currentTimeMillis());
            systemLog.setOrderNo(DateUtil.formatDate(new Date(),DateUtil.DATE_FORMAT_02)+System.currentTimeMillis());
            systemLog.setUserId("userId"+i);
            systemLog.setUserName("张三"+i);
            systemLog.setCreateTime(DateUtil.formatDate(new Date(),DateUtil.DATE_FORMAT_01));
            systemLog.setLogData("用户做了插入数据操作。")
            systemLogRepository.save(requestLog) ;
        }
        return "success" ;
    }
    @Override
    public Iterable<SystemLog> esFindAll (){
        return systemLogRepository.findAll() ;
    }
    @Override
    public String esUpdateById(SystemLog systemLog) {
        systemLogRepository.save(systemLog);
        return "success" ;
    }
    @Override
    public Optional<SystemLog> esSelectById(Long id) {
        return systemLogRepository.findById(id) ;
    }
    @Override
    public Iterable<SystemLog> esFindOrder() {
        // 用户名倒序
        // Sort sort = new Sort(Sort.Direction.DESC,"userName.keyword") ;
        // 创建时间正序
        Sort sort = new Sort(Sort.Direction.ASC,"createTime.keyword") ;
        return systemLogRepository.findAll(sort) ;
    }
    @Override
    public Iterable<SystemLog> esFindOrders() {
        List<Sort.Order> sortList = new ArrayList<>() ;
        Sort.Order sort1 = new Sort.Order(Sort.Direction.ASC,"createTime.keyword") ;
        Sort.Order sort2 = new Sort.Order(Sort.Direction.DESC,"userName.keyword") ;
        sortList.add(sort1) ;
        sortList.add(sort2) ;
        Sort orders = Sort.by(sortList) ;
        return systemLogRepository.findAll(orders) ;
    }
    @Override
    public Iterable<SystemLog> search() {
        // 全文搜索关键字
        /*
        String queryString="张三";
        QueryStringQueryBuilder builder = new QueryStringQueryBuilder(queryString);
        systemLogRepository.search(builder) ;
        */
        /*
         * 多条件查询
         */
         QueryBuilder builder = QueryBuilders.boolQuery()
                // .must(QueryBuilders.matchQuery("userName.keyword", "历张")) 搜索不到
               .must(QueryBuilders.matchQuery("userName", "张三")) // 可以搜索
               .must(QueryBuilders.matchQuery("orderNo", "20190613736278243"));
        return systemLogRepository.search(builder) ;
    }
}

总结

ElasticSearch作为强大的分布式全文搜索引擎具备许多强大的功能,通过在Spring Boot 2项目中的简单集成,可以很容易地利用ElasticSearch的搜索和查询能力,满足现代Web应用中的搜索需求。

  • 25
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Spring Boot中整合Elasticsearch(简称ES)实现全文搜索可以按照以下步骤进行操作: 1. 添加Elasticsearch依赖:在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> ``` 2. 配置Elasticsearch连接信息:在application.properties或application.yml文件中添加以下配置: ```properties spring.data.elasticsearch.cluster-name=your-cluster-name spring.data.elasticsearch.cluster-nodes=localhost:9300 ``` 3. 创建Elasticsearch实体类:创建一个Java类来映射Elasticsearch的文档结构。例如,创建一个名为`Book`的实体类: ```java @Document(indexName = "books") public class Book { @Id private String id; private String title; private String author; // getters and setters } ``` 4. 创建Elasticsearch仓库接口:创建一个继承自`ElasticsearchRepository`的接口来操作Elasticsearch。例如,创建一个名为`BookRepository`的接口: ```java public interface BookRepository extends ElasticsearchRepository<Book, String> { List<Book> findByTitleOrAuthor(String title, String author); } ``` 5. 执行搜索操作:在需要执行全文搜索的地方注入`BookRepository`,并调用相应的方法进行搜索。例如,在一个控制器中执行搜索: ```java @RestController public class BookController { @Autowired private BookRepository bookRepository; @GetMapping("/search") public List<Book> searchBooks(@RequestParam String keyword) { return bookRepository.findByTitleOrAuthor(keyword, keyword); } } ``` 以上就是在Spring Boot中整合Elasticsearch实现全文搜索的基本步骤。你可以根据自己的需求进行进一步的定制和扩展。在实际使用中,你还可以使用Elasticsearch的高级查询功能,例如模糊查询、范围查询等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值