个人博客 毕业设计4-ElasticSearch

一、搜索流程

一般来说,搜索分为2部分

  • 搜索引擎搜索:网上的资源,如百度、谷歌
  • 站内搜索:本公司数据库中的数据,如淘宝、京东

一般就是从数据库里面查找,然后定期往里面添加数据

二、ElasticSearch简介

1、概述

Elasticsearch是一个实时的分布式搜索和分析引擎。它可以帮助你用前所未有的速度去处理大规模数据。ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发 的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

人话:感觉像一个数据库,但是不需要写代码,写请求就行,请求和API对接

2、特点

  1. 可以作为一个大型分布式集群(数百台服务器)技术,处理PB级数据,服务大公 司;也可以运行在单机上
  2. 将全文检索、数据分析以及分布式技术,合并在了一起,才形成了独一无二的ES;
  3. 开箱即用的,部署简单
  4. 全文检索,同义词处理,相关度排名,复杂数据分析,海量数据的近实时处理

3、对比MySQL

在这里插入图片描述

三、走进ElasticSearch

1、安装

解压后,进入bin目录的cmd,执行命令elasticsearch,就可以启动,这一步是启动服务器
在这里插入图片描述
其中,java开发是9300,其他的是9200,因为我们还没有做java,输入http://localhost:9200/
在这里插入图片描述

2、postman调用RestAPI

1)新建索引(数据库)

put方式地址/索引名
http://127.0.0.1:9200/tensquare_elasticsearch
在这里插入图片描述

2)新建文档(列)

post方式地址/索引(数据库)/类型(表),输入json的body,这里的body相当于一列。其中,会随机生成一个"_id"的值
http://127.0.0.1:9200/tensquare_elasticsearch/article
在这里插入图片描述

3)查询全部文档(列)

GET方式地址/索引(数据库)/类型(表)/_search
http://127.0.0.1:9200/tensquare_elasticsearch/article/_search
在这里插入图片描述

4)修改文档

正常地修改

PUT方式地址/索引(数据库)/类型(表)/_id值,并且传入修改过后的body的JSON格式
http://127.0.0.1:9200/tensquare_elasticsearch/article/AXXbxviVY54hHkbLjZoO
在这里插入图片描述
前:
在这里插入图片描述
后:
在这里插入图片描述

修改一个不存在的ID

ID是随机的,我们修改一个_id为1的,因为数据库中没有,搜索会发生什么?
http://127.0.0.1:9200/tensquare_elasticsearch/article/1
在这里插入图片描述
会新建一个列
在这里插入图片描述

5)按ID查询文档(列)

GET方式地址/索引(数据库)/类型(表)/_id值
http://127.0.0.1:9200/tensquare_elasticsearch/article/1
在这里插入图片描述

6)基本匹配查询

GET方式地址/索引(数据库)/类型(表)/_search?q=下标:查找值
http://127.0.0.1:9200/tensquare_elasticsearch/article/_search?q=content:好玩
在这里插入图片描述
这个是基本匹配查询,照例来说应该是按照全部去查找而不是查找其中一部分就可以。这是因为这个引擎的基本匹配查找是按字段查找的,而每一个汉字都是一个字段,就是说每一个汉字都可以通过模糊查找。
但是英文不行,英文的一个字段是一个单词或者字母开头遇到非字母结束的那段东西,所以搜索Jav查找不到任何东西,而查找Java能查找东西
在这里插入图片描述

在这里插入图片描述

7)模糊查找

GET方式地址/索引(数据库)/类型(表)/_search?q=下标:*查找值*
http://127.0.0.1:9200/tensquare_elasticsearch/article/_search?q=content:*av*
在这里插入图片描述

8)删除文档(列)

DELET方式地址/索引(数据库)/类型(表)/_id号*
http://127.0.0.1:9200/tensquare_elasticsearch/article/1
在这里插入图片描述

四、head

1、概述

这是个对ElasticSearch进行前端界面化的工具,需要先安装node.js

2、安装

  1. 下载head插件:https://github.com/mobz/elasticsearch-head

  2. 解压

  3. 安装node.js,安装cnpm(提高速度)
    npm install -g cnpm --registry=https://registry.npm.taobao.org
    在这里插入图片描述

  4. npm install -g grunt -cli这个我也不知道是啥,做就对了
    在这里插入图片描述

  5. 安装依赖(进入head的安装目录中,主要有package.json这个就行)
    cnpm install
    在这里插入图片描述

  6. 在head目录中启动head
    grunt server
    在这里插入图片描述

这里给地址了,进入 http://localhost:9100/
在这里插入图片描述
这里显示未连接,原因:

  • 没有打开ElasticSearch
  • 跨域了

3、解决跨域问题

ElasticSearch是9200,这个head是9100,想要两者跨域,只需要在elasticsearch-5.6.8\config下的elasticsearch.yml文件尾添加

http.cors.enabled: true 
http.cors.allow-origin: "*"

然后重启ElasticSearch
在这里插入图片描述

4、操作

这个就是各图形界面化而已啦,不是软件而是浏览器的形式展示,请求什么的都一样
在这里插入图片描述
在这里插入图片描述

五、IK分词器

1、概述

没错,还要下东西,已经下了ElasticSearch搜索引擎,界面化的head,而IK分词器就是帮助我们分词的。
由于我原本没有学过ElasticSearch,所以不知道原生的分词器是怎样的(分词器就是输入一段话把其中的词拆分出来进行搜索),但是有示例,比如用原生的分词器就是
地址/_analyze?analyzer=chinese&&pretty=true&text=要搜索的词

要是搜索英文的词
http://127.0.0.1:9200/_analyze?analyzer=chinese&pretty=true&text=i am good
在这里插入图片描述
这样挺正常

要是搜索的是中文
http://127.0.0.1:9200/_analyze?analyzer=chinese&pretty=true&text=我是程序员
结果是
在这里插入图片描述
每一个词都分开了,这样很不符合搜索规范嘛,哪有这样分开搜索的。。。
所以,我们就要用IK分词器为我们提供分词,其包含了普通的词进行分词,也支持自定义分词

2、安装

  1. 下载,解压,重命名为ik
  2. 拷贝到elasticsearch-5.6.8\plugins下
  3. 重新启动elasticsearch

3、使用

其提供了两个方法

  • ik_smart 为最少切分
  • ik_max_word为最细粒度划分

ik_smart

在这里插入图片描述

ik_max_word

在这里插入图片描述

4、自定义词库

因为词条是会随着时间的推移而更新的,这个IK12年的时候就不更新了,所以,后续的词条是要我们手动添加的
在这里插入图片描述
按照现在,老铁 给力可以分为3个词条,需要我们自定义

  1. elasticsearch-5.6.8\plugins\ik\config下,创建一个.dic文件,保存格式为UTF-8

    
    老铁
    
    给力
    
    

    注意这里每一个词条上面和下面都要留一行空格,这是为了预防BUG出现,记住就行

  2. 修改elasticsearch-5.6.8\plugins\ik\config\IKAnalyzer.cfg.xml,添加文件,重新启动elasticsearch

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
    <properties>
    	<comment>IK Analyzer 扩展配置</comment>
    	<!--用户可以在这里配置自己的扩展字典 -->
    	<entry key="ext_dict">custom.dic</entry>
    	 <!--用户可以在这里配置自己的扩展停止词字典-->
    	<entry key="ext_stopwords"></entry>
    	<!--用户可以在这里配置远程扩展字典 -->
    	<!-- <entry key="remote_ext_dict">words_location</entry> -->
    	<!--用户可以在这里配置远程扩展停止词字典-->
    	<!-- <entry key="remote_ext_stopwords">words_location</entry> -->
    </properties>
    

在这里插入图片描述

六、elasticsearch7.X

1、更新换代

由于笔者看的视频是18年的,那时还是elasticsearch 5.x,底层是5.x,但是现在20年elasticsearch大多是7.x了,yml、IK词条、配置已经完全不一样了。而且,7.x没有type(表)这么一个概念了。所以,要再重新学一遍elasticsearch 7.x

2、下载

在官网下,elasticsearchIK的版本要一致,那些安装和上面的一样,head不用变,步骤比较多,不要漏任何一步

3、postman调用RestAPI

rest一样,更加详细的在这里

4、不一样的地方

IK分词器

安装还是这么安装,但用法不一样,7.x是
GET方式 地址/_analyze?pretty=true,body为:

{
    
    
	"analyzer":"ik_smart / ik_max_word",
	"下标": "查找字"
}

在这里插入图片描述

其他

  • 7.x版本只运行一个type,后面的type不管起什么名字,都没用,都是会放在第一个type的
  • 控制版本要和本地的一样,在父pom中
    <properties>
        <java.version>1.8</java.version>
        <!--        这里要一样-->
        <elasticsearch.version>7.10.0</elasticsearch.version>
    </properties>
    

七、微服务模块

1、导包与更新换代

  • 本项目pom
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
            <version>2.3.4.RELEASE</version>
        </dependency>
  • 父项目pom
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
<!--        这里要一样-->
        <elasticsearch.version>7.10.0</elasticsearch.version>
    </properties>

2、config

需要创建一个设置类


//照抄就行,官网得
@Configuration
public class ElasticsearchConfig extends AbstractElasticsearchConfiguration {
    
    

    @Override
    public RestHighLevelClient elasticsearchClient() {
    
    
        final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
                .connectedTo("localhost:9200")
                .build();
        return RestClients.create(clientConfiguration).rest();
    }
}

3、实体层


//对应elasticsearch的index 和 type
@Document(indexName = "tensquare_test")
@Data
public class Article implements Serializable {
    
    
    @Id
    private String id;

    /*
    @Field干嘛的
    是否索引,就是看该域是否能被搜索(面试回答)
    是否分词,就表示搜索的时候是整体匹配还是单词匹配
    是否存储,就是是否在页面上显示
     */
    @Field(index = true,analyzer = "ik_max_word",searchAnalyzer = "ik_max_word")
    private String title;

    @Field(index = true,analyzer = "ik_max_word",searchAnalyzer = "ik_max_word")
    private String content;

    private String state;
}

  • @Document(indexName = "tensquare_test")对应哪个数据库
  • @Field写就对了,index=true表明这个字段可以被搜索到。另外两个都是让搜索变为IK搜索方式

4、3层设置

dao

public interface ArticleDao extends ElasticsearchRepository<Article,String> {
    
    
}

service


@Service
public class ArticleService {
    
    
    @Autowired
    private ArticleDao articleDao;
    @Autowired
    private IdWorker idWorker;

    public void add(Article article){
    
    
        article.setId(idWorker.nextId()+"");
        articleDao.save(article);
    }

    public void deleteById(String id){
    
    
        articleDao.deleteById(id);
    }

}

controller


@RestController
@CrossOrigin
@RequestMapping("/article")
public class ArticleController {
    
    
    @Autowired
    private ArticleService articleService;

    @PostMapping("")
    public Result save(@RequestBody Article article){
    
    
        articleService.add(article);
        return new Result(true, StatusCode.OK,"添加成功");
    }

    @DeleteMapping("{id}")
    public Result deleteById(@PathVariable String id){
    
    
        articleService.deleteById(id);
        return new Result(true,StatusCode.OK,"删除成功");
    }
}

在这里插入图片描述
在这里插入图片描述

5、查询数据

传统艺能

public interface ArticleDao extends ElasticsearchRepository<Article,String> {
    
    

    //查找
    public Page<Article> findByTitleOrContentLike(String title, String content, Pageable p);
}
    public Page<Article> findByTitleOrContentLike(String keyword,int page,int size){
    
    
        Pageable pageable = PageRequest.of(page-1, size);
        return  articleDao.findByTitleOrContentLike(keyword,keyword,pageable);
    }
    @GetMapping("search/{keyword}/{page}/{size}")
    public Result findByTitleOrContentLike(@PathVariable String keyword,@PathVariable int page,@PathVariable int size){
    
    
        Page<Article> articles = articleService.findByTitleOrContentLike(keyword, page, size);
        return new Result(true,StatusCode.OK,"查询成功",new PageResult<Article>(articles.getTotalElements(),articles.getContent()));
    }

在这里插入图片描述
在这里插入图片描述

八、利用Logstash进行ES与MySQL数据同步

1、Logstash

Logstash是一款轻量级的日志搜集处理框架,可以方便的把分散的、多样化的日志搜集 起来,并进行自定义的处理,然后传输到指定的位置,比如某个服务器或者文件。

人话:ES是一个数据库,MySQL也是一个数据库,但是我们查找是用ES,但源数据的增删改用的是MySQL,而Logstash就是用来自动将MySQL的数据转移到ES的

2、Logstash安装与测试

由于Logstash5.X的我电脑运行不了,所以换了7.62版本。
至今为止,ES,Logstash,IK,都是用7.X版本的
解压,进入bin目录,cmd
logstash -f 文件路径
而其中的文件路径,就是我们用MySQL导入ES的文件,语法什么的都是固定的

这个文件起名xx.conf就行,我这里设置为根目录/mysqletc/mysql.conf,这个是模块

input {
  jdbc {
	  # mysql jdbc connection string to our backup databse
	  jdbc_connection_string => ""
	  # the user we wish to excute our statement as
	  jdbc_user => ""
	  jdbc_password => ""
	  # the path to our downloaded jdbc driver  
	  jdbc_driver_library => ""
	  # the name of the driver class for mysql
	  jdbc_driver_class => "com.mysql.jdbc.Driver"
	  jdbc_paging_enabled => ""
	  jdbc_page_size => ""
	  #以下对应着要执行的sql的绝对路径。
	  #statement_filepath => ""
	  statement => ""
	  #定时字段 各字段含义(由左至右)分、时、天、月、年,全部为*默认含义为每分钟都更新(测试结果,不同的话请留言指出)
      schedule => "* * * * *"
  }
}

output {
  elasticsearch {
	  #ESIP地址与端口
	  hosts => "" 
	  #ES索引名称(自己定义的)
	  index => ""
	  #自增ID编号
	  document_id => "%{id}"
	  document_type => ""
  }
  stdout {
      #以JSON格式输出
      codec => json_lines
  }
}

这个是正文

input {
  jdbc {
	  # mysql jdbc connection string to our backup databse
	  #这个是MySQL的数据库,就是之前article的yml的MySQL数据源
	  ##注意要加useSSL=false
	  jdbc_connection_string => "jdbc:mysql://192.168.12.128:3306/tensquare_article?characterEncoding=UTF8&useSSL=false"
	  # the user we wish to excute our statement as
	  #账号
	  jdbc_user => "root"
	  #密码
	  jdbc_password => "root"
	  # the path to our downloaded jdbc driver  
	  #MySQL连接Java的jar包,自己下载
	  jdbc_driver_library => "D:\tools\logstash-7.6.2\mysqletc\mysql-connector-java-5.1.46.jar"
	  # the name of the driver class for mysql
	  jdbc_driver_class => "com.mysql.jdbc.Driver"
	  #是否分页
	  jdbc_paging_enabled => "true"
	  #分页数据大小
	  jdbc_page_size => "50000"
	  #以下对应着要执行的sql的绝对路径。
	  #下面写查询语句,将该查询语句导入ES中
	  #statement_filepath => ""
	  statement => "SELECT id,title,content,state FROM tb_article"
	  #定时字段 各字段含义(由左至右)分、时、天、月、年,全部为*默认含义为每分钟都更新(测试结果,不同的话请留言指出)
	  #全是*,就是每分钟更新一次
      schedule => "* * * * *"
  }
}

output {
  elasticsearch {
	  #ESIP地址与端口
	  hosts => "127.0.0.1:9200" 
	  #ES索引名称(自己定义的)
	  index => "tensquare_article"
	  #自增ID编号
	  document_id => "%{id}"
	  document_type => "_doc"
  }
  stdout {
      #以JSON格式输出
      codec => json_lines
  }
}

  • 注意点:数据源要加入useSSL=false

然后在bin中输入logstash -f ../mysqletc/mysql.conf
在这里插入图片描述
已经开始更新了
在这里插入图片描述
但是!我们至今为止做的操作,ES和Logstash是本地的,用本地做测试一遍,就先不会晕,接下来就是在docker中操作了

3、特性

虽然很美好,但还是有缺点的,在MySQL中删除的东西,同步到Logstash中并不会删除,还是会在Logstash保存记录的。而我们的做法一般都是Logstash只做查询不做增删改。

  • 解决方法:MySQL中,删除一个数据不要真的删,添加一个列state,为0就表示删除,1表示没被删除,这样,查的时候就查询state=1的值就行。

九、docker中安装与运行

docker的国内加速在我之前的docker文章中有说

1、ES

注意我们要用ES 7.X的,如果默认下载lates,就只会是5.x

1)安装

安装的版本链接
看版本是什么,我用的是
docker pull elasticsearch:7.9.3

2)创建容器

docker run -di --name=tensquare_es -p 9200:9200 -p 9300:9300 elasticsearch:7.9.3

3)一系列的BUG与解决

参考链接:
https://blog.csdn.net/qq_43511351/article/details/105283867
https://blog.csdn.net/qq_43655835/article/details/104637625

①系统调优

这样创建了并且启动了,但是!这样会因为默认JVM内存不够而自动关掉

修改/etc/security/limits.conf ,追加内容

vi /etc/security/limits.conf,添加

* soft nofile 65536 
* hard nofile 65536

nofile是单个进程允许打开的最大文件个数 soft nofile 是软限制 hard nofile是硬限制
在这里插入图片描述

修改/etc/sysctl.conf,追加内容

vi /etc/sysctl.conf,追加内容

vm.max_map_count=655360

在这里插入图片描述

执行命令,重启虚拟机

执行这条命令sysctl ‐p
然后手动重启

②出现新的BUG

看BUG是啥

原本以为,弄好上面的内存大小,就好了,没想到一启动,还是错,查看错误日志
docker logs -f 容器ID
出现错误
在这里插入图片描述

ERROR: [1] bootstrap checks failed
[1]: the default discovery settings are unsuitable for production use; at least one of [discovery.seed_hosts, discovery.seed_providers, cluster.initial_master_nodes] must be configured
ERROR: Elasticsearch did not exit normally - check the logs at /usr/share/elasticsearch/logs/docker-cluster.log

翻译过来就是默认的设置不适合生产使用,意思就是你必须要配置[discovery.seed_hosts, discovery.seed_providers, cluster.initial_master_nodes]之一。然后根据上网找的资料找到下面的那条命令。。

解决步骤

只能先删除原本的镜像了
在这里插入图片描述
再执行命令
docker run -di --name=tensquare_es -e ES_JAVA_POTS="-Xms256m -Xmx256m" -e "discovery.type=single-node" -p 9200:9200 -p 9300:9300 elasticsearch:7.9.3

  • 这一次启动修改配置文件 第一个是修改jvm的内存 第二个是表面这个es是单个节点
    在这里插入图片描述

访问http://192.168.12.128:9200/
在这里插入图片描述
看到可以访问,感动哭了,2天的BUG就快做好了

测试

修改Java文件,把ElasticsearchConfig修改

//照抄就行,官网得
@Configuration
public class ElasticsearchConfig extends AbstractElasticsearchConfiguration {
    
    

    @Override
    public RestHighLevelClient elasticsearchClient() {
    
    
        final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
        		//这里改成docker的地址
                .connectedTo("192.168.12.128:9200")
                .build();
        return RestClients.create(clientConfiguration).rest();
    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
成功了!!!!!!

②开启远程连接

上面是连接了,但是win的head端连接不了啊。
在这里插入图片描述
elasticsearch 5.x版本后就默认不开启远程连接,上面的head操作的时候,是进入到elasticsearch-7.10.0\config\elasticsearch.yml添加东西的。这个思路在Linux也是一样,找到文件然后修改文件。

我的版本(新版)

查看文件docker exec -it tensquare_es /bin/bash
在这里插入图片描述
这个进入到容器了,查看有什么文件
在这里插入图片描述
有config文件夹,和win的一样,修改config\elasticsearch.yml即可
在这里插入图片描述
编辑vi elasticsearch.yml,添加下列文字,保存

http.cors.enabled: true 
http.cors.allow-origin: "*"

在这里插入图片描述
重启改容器docker restart tensquare_es

测试

启动win的head,连接
在这里插入图片描述

老版本

老版本不能直接进入文件里面修改的,要挂载什么的。以下是复制粘贴的文章
在这里插入图片描述

2、IK分词器

还没有安装IK分词器
在这里插入图片描述
操作是一样的,把win的IK分词器下好,再放到虚拟机中的相同目录
win是把IK文件(把自定义的也弄好了的)放到elasticsearch-7.10.0\plugins中。
Linux也一样

1)把win的IK传送到虚拟机中

注意,ES的版本要和IK的版本一模一样才可以,不然的话会错误。解决链接

用xftp,进行win和虚拟机的交互在这里插入图片描述
在这里插入图片描述

2)把虚拟机中的IK拷贝到容器中

放到虚拟机中了,再把虚拟机中的IK文件拷贝到容器/usr/share/elasticsearch/plugins/

①拷贝到容器中

docker cp ik tensquare_es:/usr/share/elasticsearch/plugins/

②重启

docker restart tensquare_es
在这里插入图片描述

3、head

这个得先允许ES跨域,这个在之前就做了

1)下载安装

下载header7.x(5.x用不了)
docker pull mobz/elasticsearch-head:5
创建容器
docker run -di --name=tensquare_header -p 9100:9100 mobz/elasticsearch-head:5

2)有BUG

这里可以进去,但是查不到数据
在这里插入图片描述

3)解决BUG

原因:
elasticsearch 6增加了请求头严格校验的原因,并且返回结果是

{
    
    
“error” : “Content-Type header [application/x-www-form-urlencoded] is not supported”,
“status” : 406
}

进入head插件安装目录 ,编辑/usr/src/app/_site/vendor.js

容器编辑不了点击链接

修改共有两处:

第6886行 : contentType: “application/x-www-form-urlencoded”
改为 contentType: “application/json;charset=UTF-8”

第7573行: var inspectData = s.contentType === “application/x-www-form-urlencoded” &&
改为 var inspectData = s.contentType === “application/json;charset=UTF-8” &&

PS:

vim中显示行号的命令为

:set nu

vim中跳转到指定行的命令为

:行号(esc 再: ,再输入,6886)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4、记得修改logstash\mysqletc\mysql.conf中ES的IP与IP

猜你喜欢

转载自blog.csdn.net/yi742891270/article/details/109787300