Elasticsearch搜索和分析引擎
环境搭建
下载安装ElasticSearch 5.6.8
- 下载ElasticSearch 5.6.8版本,无需安装,解压安装包后即可使用,注意安装目录路径中不能有中文
https://www.elastic.co/downloads/past-releases/elasticsearch-5-6-8 - 进入ElasticSearch安装目录下的bin目录,打开黑窗口,执行命令
elasticsearch
即可启动。 - 浏览器,在地址栏输入http://127.0.0.1:9200/ 即可看到输出结果
下载安装ElasticSearch 5.6.8的图形化界面
- 使用图形化界面来实现Elasticsearch的日常管理,最常用的就是Head插件
- 下载head插件:https://github.com/mobz/elasticsearch-head
- 解压到任意目录,但是要和elasticsearch的安装目录区别开,安装目录路径下不能有中文
- 黑窗口安装cnpm
npm install -g cnpm --registry=https://registry.npm.taobao.org - 将grunt安装为全局命令 。Grunt是基于Node.js的项目构建工具。它可以自动运行你所 设定的任务
npm install -g grunt -cli - 黑窗口进入elasticsearch-head-master目录安装依赖
cnpm install - 进入elasticsearch-head-master目录启动head,在命令提示符下输入命令
grunt server - 修改elasticsearch的配置文件,让其允许跨域访问。
修改elasticsearch配置文件:elasticsearch.yml,增加以下两句命令:
http.cors.enabled: true
http.cors.allow-origin: “*” - 打开浏览器,输入 http://localhost:9100
这样我们就可以用head连接9200的elasticsearch了
下载中文分词器
- 下载地址:https://github.com/medcl/elasticsearch-analysis-ik/releases
- 先将其解压,将解压后的elasticsearch文件夹重命名文件夹为ik
- 将ik文件夹拷贝到elasticsearch/plugins 目录下。
- 重新启动,即可加载IK分词器
IK提供了两个分词算法ik_smart 和 ik_max_word,其中 ik_smart 为最少切分,ik_max_word为最细粒度划分
案例:
最小切分:在浏览器地址栏输入地址
http://127.0.0.1:9200/_analyze?analyzer=ik_smart&pretty=true&text=我是程序员
结果显示:
elasticsearch与MySQL数据同步
- 解压logstash-5.6.8.zip,进入bin目录,打开黑窗口,测试输入输出
Logstash -e ‘input{stdin{}} output{stdout{}}’
- MySQL数据导入Elasticsearch
(1)在logstash-5.6.8安装目录下创建文件夹mysqletc (资料提供)(名称随意)
(2)文件夹下创建mysql.conf (名称随意) ,内容如下:注意修改数据库url,用户名和密码,修改jdbc_driver_library的依赖路径
input {
jdbc {
# mysql jdbc connection string to our backup databse
jdbc_connection_string => "jdbc:mysql://192.168.200.157:3306/tensquare_article?characterEncoding=utf-8"
# the user we wish to excute our statement as
jdbc_user => "root"
jdbc_password => "cqrjxk39"
# the path to our downloaded jdbc driver
jdbc_driver_library => "D:\elasticsearch\logstash-5.6.8\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 => "50"
#以下对应着要执行的sql的绝对路径。
#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 => "article"
}
stdout {
#以JSON格式输出
codec => json_lines
}
}
(3) 在文件夹下添加依赖mysql-connector-java-5.1.46.jar
- 在bin目录下执行命令(按mysql.conf执行)
logstash -f …/mysqletc/mysql.conf
- 再次刷新elasticsearch-head的数据显示
前期准备
依赖注入
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<!--搜索引擎依赖-->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
</dependency>
<!--springBoot依赖-->
<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>
</dependencies>
<repositories>
<!--指定仓库下载地址-->
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<!--指定插件下载地址-->
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
配置文件
server:
port: 9007
spring:
application:
#不推荐写下划线
name: tensquare-search
data:
elasticsearch:
cluster-nodes: 127.0.0.1:9300
springBoot启动类
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SearchApplication {
public static void main(String[] args) {
SpringApplication.run(SearchApplication.class,args);
}
}
核心代码
pojo层
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import java.io.Serializable;
//指定数据库名和表名
@Data
@Document(indexName = "tensquare_article",type = "article")//指定数据库,指定该类型
public class Article implements Serializable {
@Id//指定主键
private String id;//ID
@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;//审核状态
}
dao层
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
public interface ArticleDao extends ElasticsearchRepository<Article,String> {
//这里的名字不能乱起
public Page<Article> findByTitleOrContentLike(String title, String content, Pageable pageable);
}
service层
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional
public class ArticleService {
@Autowired
private ArticleDao articleDao;
public void addArticle(Article article){
articleDao.save(article);
}
public Page<Article> findByTitleOrContentLike(String title,String content,int page,int size){
PageRequest of = PageRequest.of(page - 1, size);
Page<Article> byTitleOrContentLike = articleDao.findByTitleOrContentLike(title, content, of);
return byTitleOrContentLike;
}
}
controller层
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;
@RestController
@CrossOrigin
@RequestMapping("/article")
public class ArticleController {
@Autowired
private ArticleService articleService;
@RequestMapping(method = RequestMethod.POST)
public Result addArticle(@RequestBody Article article){
articleService.addArticle(article);
return new Result(true, StatusCode.OK,"插入成功",null);
}
@RequestMapping(value = "/{key}/{page}/{size}",method =RequestMethod.GET)
public Result findByTitleOrContentLike(@PathVariable String key,@PathVariable int page,@PathVariable int size){
Page<Article> byTitleOrContentLike = articleService.findByTitleOrContentLike(key, key, page, size);
return new Result(true,StatusCode.OK,"查询成功",new PageResult<Article>(byTitleOrContentLike.getTotalElements(),byTitleOrContentLike.getContent()));
}
}