大型项目必备搜索神器,搜索引擎ElasticSearch详细教程
项目必备组件,站内搜索神器ElasticSearch详细教程,包含Elasticsearch的概念,环境搭建,ik分词器安装,ES存储形式,正向索引和倒排索引,以及ES索引库的基本操作、ES文档操作,以及Springboot集成ES。
目录
一、ES概述
1. ElasticSearch简称ES,是一个基于 Lucene 库的开源搜索引擎。
2. 它提供了一个分布式、多用户能力的全文搜索引擎,具有高可扩展性、高可用性等特点。
3. ES可以帮助我们从海量数据中快速找到需要的内容,它可以近乎实时的存储、检索数据,还可以实现日志统计、分析、系统监控等功能。
ElasticSearch官网传送门:Elastic — The Search AI Company | Elastic
4. 注意 Elasticsearch所提供的是站内搜索功能。
- 站内搜索是指在一个网站内部进行信息检索的功能,它允许用户通过输入关键词等方式,快速找到网站内相关的网页、产品、文章、文档等内容。
- 例如在拼多多、京东、淘宝等网站搜索我们想要购买的商品;在抖音搜索我们想看的短视频等,这些都属于是站内搜索。
- 而我们通常在浏览器网页或百度进行搜索就不属于是站内搜索了。
二、ES环境搭建
2.1 安装ES
7.6.1 版下载:
https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.6.1-windows-x86_64.zip
下载后进行解压:
在bin目录中,双击启动elasticsearch.bat (启动要依赖于JDK, 确保JDK无误)
成功启动后,在浏览器访问9200端口,若显示相关信息则表示我们的ES服务没有问题:
2.2 安装数据可视化界面
elasticsearch-head 是一个可视化界面,可以浏览ES中的数据。
注意:前提需要安装node.js
github下载:https://github.com/mobz/elasticsearch-head/ (下载可能较慢)
下载后进行解压:
由于从界面访问9200服务会出现跨域问题,所以需要在config 目录中的 elasticsearch.yml 文件中进行配置: ( 注意是elasticsearch文件夹中的config目录 )
# 开启跨域
http.cors.enabled: true
# 所有人访问
http.cors.allow-origin: "*"
在elasticsearch-head-master目录下通过cmd命令打开终端:
浏览器访问后出现如图的可视化界面,表示成功:
2.3 安装可视化kibana组件
kibana也是一个可视化组件,在里面进行命令操作.
7.6.1 下载版:
https://artifacts.elastic.co/downloads/kibana/kibana-7.6.1-windows-x86_64.zip
下载后进行解压:
汉化kibana:修改config 目录下的kibana.yml 文件:
i18n.locale: "zh-CN"
双击bin目录下的kibana.bat启动:(启动较慢)
访问 http://127.0.0.1:5601
注意之前启动的终端不能关闭,此时已经启动三个终端了!
2.4 安装IK分词器
在 elasticsearch-7.6.1 \ plugins 目录下创建名称为 ik的文件夹,将解压后的文件复制到 ik目录:
自定义ik分词器:(根据实际情况选择配置,在config目录下)
自定义后还需要在 IKAnalyzer.cfg.xml 文件中对自己定义的字典(分词器)进行注册:
每次修改配置后都需要重启终端!
上述下载链接打不开的可以私信博主!
三、ES基本概念
3.1 ES存储形式
Elasticsearch是面向文档存储的,可以是数据库中的一条商品数据,一个订单信息。文档数据会被序列化为 json格式后存储在Elasticsearch中。
索引:同类型文档的集合,类似数据库中的表.
文档:一条数据就是一个文档,类似于mysql中的一条记录,es中是json格式的.
字段:json文档中的字段.
映射:索引中文档的约束,比如字段名称、类型.
关系型数据库 MySQL 和 Elasticsearch 对比:
mysql负责安全可靠的存储原始数据,以及数据之间的关系;elasticsearch负责进行数据搜索。
3.2 正向索引和倒排索引
mysql 采用正向索引,即基于文档 id创建索引,查询词条时必须先找到文档,而后判断是否包含搜索的内容。
文档(document):每条数据就是一个文档 。
词条(term):文档按照语义分成的词语。
Elasticsearch 采用倒排索引: 从关键词的角度来构建索引,记录了每个关键词出现在哪些文档中.
- 简单来说,正向索引就像是一本书的目录,按照章节(文档)顺序,列出每个章节(文档)里出现的重要词汇(关键词)。
- 而倒排索引可以把它想象成一个词汇表,每个词汇后面跟着包含这个词汇的文档列表。
四、ES索引库基本操作
4.1 创建索引库
这里我以创建一个新闻索引库为实例进行演示:
PUT /news
{
"mappings": {
"properties": {
"id":{
"type": "integer",
"index": false
},
"title":{
"type": "text",
"analyzer": "ik_max_word"
},
"img":{
"type": "keyword",
"index": false
},
"operTime":{
"type": "date",
"index": false
}
}
}
}
mapping 是对索引库中文档的约束,常见的mapping属性包括:
type:字段数据类型,常见的简单类型有:
字符串:text(可分词的文本),keyword(精确值,例如:品牌, 国家, 邮箱)
数值:long、integer、short、byte、double、float
布尔:boolean
日期:date
对象:object
index:是否创建索引参与搜索,默认为true,如果不需要参与搜索设置为false.
analyzer:使用哪种分词器.
4.2 查询索引库
GET /索引库名
4.3 删除索引库
DELETE /索引库名
4.4 修改索引库
索引库和mapping一旦创建无法修改,但是可以添加新的字段,语法如下:
例如为新闻索引库添加了一个 dzcount(点赞数量) 的字段:
PUT /news/_mapping
{
"properties":{
"dzcount":{
"type":"long",
"index":false
}
}
}
五、ES文档操作
5.1 新增文档
语法:
POST /索引库名/_doc/文档id
{
" 字段名1 " : " 值1 "
" 字段名2 " : " 值2 " .....
}
我们以上述新闻索引库为例,新增三条文档:
POST /news/_doc/1
{
"id":1,
"title":"华为手机正在热卖中",
"img":"101.jpg",
"dzcount":350
}
POST /news/_doc/2
{
"id":2,
"title":"小米手机,性价比之王",
"img":"102.jpg",
"dzcount":400
}
POST /news/_doc/3
{
"id":3,
"title":"小米汽车销量创新高",
"img":"103.jpg",
"dzcount":300
}
5.2 查询文档
语法:GET /索引库名/_doc/文档id
GET /news/_doc/1
5.3 删除文档
语法:DELETE /索引库名/_doc/文档id
DELETE /news/_doc/1
5.4 修改文档
POST /news/_update/4
{
"doc": {
title:"鸿蒙系统正式发布,实现遥遥领先"
}
}
5.5 搜索文档
GET /news/_search
{
"query": {
"match": {
"title": "小米手机"
}
}
}
六、Springboot 集成 ES
6.1 搭建
1. 指定版本 (版本必须与安装的ES版本一致)
<properties>
<java.version>1.8</java.version>
<elasticsearch.version>7.6.1</elasticsearch.version>
</properties>
2. 添加依赖
<!-- ES -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
</dependency>
3. 添加初始化 RestHighLevelClient的配置类
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ElasticSearchConfig {
@Bean
public RestHighLevelClient restHighLevelClient(){
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http")));
return client;
}
}
6.2 索引库操作
创建索引库:
CreateIndexRequest request = new CreateIndexRequest("users");
CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(request,
RequestOptions.DEFAULT);
判断索引库是否存在:
GetIndexRequest request = new GetIndexRequest("users");
boolean exists = restHighLevelClient.indices().exists(request,RequestOptions.DEFAULT);
删除索引库:
DeleteIndexRequest indexRequest = new DeleteIndexRequest("users");
AcknowledgedResponse delete = restHighLevelClient.indices().delete(indexRequest,
RequestOptions.DEFAULT);
delete.isAcknowledged();//返回true删除成功,返回false删除失败
6.3 文档操作
添加文档:
//将新闻添加到mysql的同时,将数据同步更新到ES,为搜索提供数据
News news =new News();
news.setId(3);
news.setTitle("美国今年要总统选择,拜登着急了");
news.setImg("aaaaasssss.jpg");
IndexRequest indexRequest=new IndexRequest("news").id(news.getId().toString());
//将对象转为json存进ES
indexRequest.source(newObjectMapper().writeValueAsString(news),XContentType.JSON);
restHighLevelClient.index(indexRequest,RequestOptions.DEFAULT);
修改文档:
News news = new News();
news.setId(3);
news.setTitle("中国航母开往美国,准备开战,拜登着急了");
news.setImg("dddddddddddd.jpg");
UpdateRequest updateRequest = new UpdateRequest("news", news.getId().toString());
updateRequest.doc(newObjectMapper().writeValueAsString(news), XContentType.JSON);
restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
查询文档:
GetRequest getRequest = new GetRequest("news", "1");
GetResponse getResponse = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
//获取查询的内容,返回json格式
String json = getResponse.getSourceAsString();
//使用jackson组件将json字符串解析为对象
News news = new ObjectMapper().readValue(json, News.class);
删除文档:
DeleteRequest deleteRequest = new DeleteRequest("news", "1");
DeleteResponse delete = restHighLevelClient.delete(deleteRequest,RequestOptions.DEFAULT);
搜索文档:
SearchRequest searchRequest = new SearchRequest("news");
SearchRequest searchRequest = new SearchRequest("news");
//精确条件查询
searchRequest.source().query(QueryBuilders.termQuery("title", "美国"));
//发送查询请求
SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
//接收查询结果
SearchHits hits = search.getHits();
//组装查询结果
ArrayList<News> list = new ArrayList<>();
//取出结果集
for (SearchHitsearchHit:hits.getHits()) {
String json = searchHit.getSourceAsString();
News news = new ObjectMapper().readValue(json, News.class);
list.add(news);
}
🌸🌸🌸 完结撒花 🌸🌸🌸
博主WX:g2279605572 欢迎大家与我交流!
更多推荐
所有评论(0)