一、ES介绍
1、安装
(1) Elasticsearch
elastic的官网 elastic.co/downloads/elasticsearch 获取最新版本的Elasticsearch。解压文档后,按照下面的操作
cd elasticsearch-<version>
./bin/elasticsearch.bat
此时,Elasticsearch运行在本地的9200端口,在浏览器中输入网址“http://localhost:9200/”
如果想要获取到过往版本,可以访问:
Elasticsearch:https://www.elastic.co/guide/en/elasticsearch/reference/7.3/zip-windows.html
7.3.2版本的具体下载地址
Elasticsearch: https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.3.2-windows-x86_64.zip
(2)Kibana
如果想要图形化界面,可以安装Kibana
Kibana-官网: https://www.elastic.co/guide/en/kibana/7.3/install.html
Kibana-7.3.2: https://artifacts.elastic.co/downloads/kibana/kibana-7.3.2-windows-x86_64.zip
修改config/kibana.yml文件
cd elasticsearch-<version>
./bin/kibana.bat
此时,Kibana运行在本地的5601端口,在浏览器中输入网址“http://localhost:5601/”
(3)IK
如果想要设置ik分词,下载与Elasticsearch一致的版本
github地址: https://github.com/infinilabs/analysis-ik
下载地址: https://release.infinilabs.com/analysis-ik/stable/
在elasticsearch的plugins文件夹下新建ik文件夹,将ik解压复制到ik下
重启es和kibana,验证ik是否安装成功
IK分词器有三种模式,tokenizer可以选择下面其中一种
- standard:默认
- ik_smart:智能切分,粗粒度
- ik_max_word:最细切分,细粒度IK分词器
但是新出现的词语无法识别,需要手动维护词典库
<?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"></entry>
<!--用户可以在这里配置自己的扩展停止词字典-->
<entry key="ext_stopwords"></entry>
<!--用户可以在这里配置远程扩展字典 -->
<!-- <entry key="remote_ext_dict">words_location</entry> -->
<!--用户可以在这里配置远程扩展停止词字典-->
<!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>
2、概念
(1)倒排索引
- 正向索引:基于文档id创建索引。根据id查询快,但是查询词条时必须先找到文档,而后判断是否包含词条。
- 倒排索引:对文档内容分词,对词条创建索引,并记录词条所在文档的id,查询时先根据词条查询到文档id,而后根据文档id查询文档
传统数据库(如MySQL)采用正向索引,例如给下表(goods)中的id创建索引:
elasticsearch采用倒排索引:
- 文档(document):每条数据就是一个文档
- 词条(term):文档按照语义分成的词语
(2)基础概念
elasticsearch | mysql |
---|---|
索引 | 表 |
文档 | 行 |
字段 | 列 |
3、postman访问命令
(1)索引
创建索引:
发送put请求:http://localhost:9200/索引名
查询索引集合
发送get请求:http://localhost:9200/_cat/indices?v
查询索引信息
发送get请求:http://localhost:9200/google
删除索引
发送delete请求:http://localhost:9200/google
Kibana对应界面
(2)文档
创建文档
使用put方式请求:http://localhost:9200/索引名/_doc/自定义id
注意:如果没有自定义id,则要使用post方式请求。生成随机id
查询文档集合
get请求:http://localhost:9200/索引/_search
注意:postman的body中不能有数据
查询单条文档
get请求:http://localhost:9200/索引/_doc/数据id
条件查询文档
发送get请求:http://localhost:9200/索引/_search,在请求body中写条件
{
"query": {
"match": {
"字段": "查询条件"
}
}
}
注意1:如果只想查询所需字段,可以添加查询参数 "_source": "{field}"
{
"query": {
"match": {
"title": "小米"
}
},
"_source": "title"
}
注意2:如果想按照某字段排序,可以添加查询参数 "sort"
"sort": [
{
"FIELD": {
"order": "desc"
}
}
]
注意3:复核查询。如果某字段满足多个条件,可以添加查询参数 "bool"
- must:必须匹配每个子查询,类似“与”
- should:选择性匹配子查询,类似“或”
- must_not:必须不匹配,不参与算分,类似“非”
- filter:必须匹配,不参与算分
GET /items/_search
{
"query": {
"bool": {
"must": [
{"match": {"name": "手机"}}
],
"should": [
{"term": {"brand": { "value": "vivo" }}},
{"term": {"brand": { "value": "小米" }}}
],
"must_not": [
{"range": {"price": {"gte": 2500}}}
],
"filter": [
{"range": {"price": {"lte": 1000}}}
]
}
}
}
{
"query": {
"bool": {
# 只要有小米或者华为的就满足
"should": [
{
"match": {
"title": "小米"
}
},
{
"match": {
"title": "华为"
}
}
]
}
}
}
{
"query": {
"bool": {
# 既要有小米,又要有华为
"must": [
{
"match": {
"title": "小米"
}
},
{
"match": {
"title": "华为"
}
}
]
}
}
}
注意4:如果想要完全匹配,可以添加查询参数 "match_phrase"
。
{
"query": {
"match_phrase": {
#查询出数据 “小米手机”和“小米手环”
"title": "小米"
#查询出数据 “小米手机”
"title": "小米手机"
#查询空数据
"title": "小米电脑"
}
}
}
注意5:精确查询。词条级别的查询。也就是说不会对用户输入的搜索条件再分词,而是作为一个词条,与搜索的字段内容精确值匹配。因此推荐查找keyword、数值、日期、boolean类型的字段。包括id,term,range三种方式
GET /{索引库名}/_search
{
"query": {
"ids": {
"values": [id]
}
}
}
GET /{索引库名}/_search
{
"query": {
"term": {
"字段名": {
"value": "搜索条件"
}
}
}
}
GET /{索引库名}/_search
{
"query": {
"range": {
"字段名": {
"gte": {最小值},
"lte": {最大值}
}
}
}
}
分页查询文档
发送get请求:http://localhost:9200/索引/_search,在请求body中写条件
{
"query": {
"match": {
"字段": "查询条件"
},
"from": 0, # 第几页
"size": 1 # 每页多少
}
}
高亮查询
GET student/_search
{
"query": {
"match": {
"字段": "查询条件"
}
}
, "highlight": {
"fields": {
"字段": {
"pre_tags": "<em>",
"post_tags": "</em>"
}
}
}
}
修改文档
1.全量修改:
发送put请求:http://localhost:9200/索引/_doc/数据id
和创建文档一样,数据id不存在则新建,存在则修改
2.局部修改:
发送post请求:http://localhost:9200/索引/_update/id
修改内容要放到doc中。
{
"doc": {
"title": "华为电脑"
}
}
删除文档
发送delete请求:http://localhost:9200/索引/_doc/数据id
(3)映射
elasticsearch中的映射就类似于mysql中的表的各种信息,如字段的长度等。
put请求创建索引:http://localhost:9200/student
put请求添加映射:http://localhost:9200/student/_mapping
- test:表示文本,是可以分词的,即查询条件只要是其中的一个分词也可以匹配。
- keyword表示完整匹配,不能分词,即查询条件必须完全匹配才可以
- index true表示可以索引查询的,false表示不可以索引查询
get请求查询映射:http://localhost:9200/student/_mapping
按照sno查询失败
二、SpringBoot整合
SpringBoot默认支持两种技术来和ES交互:
- Jest(默认不生效)
- SpringData ElasticSearch
1、Jest
需要导入jest的工具包(io.searchbox.client.JestClient)
(1)核心依赖
<dependency>
<groupId>io.searchbox</groupId>
<artifactId>jest</artifactId>
<version>6.3.1</version>
</dependency>
(2)配置文件
spring.elasticsearch.jestt.uris=192.168.99.100:9200
(3)实体类配置
@Data
public class Article {
@JestId
private Integer id;
private String author;
private String title;
private String content;
(4)调用
@Autowired
JestClient jestClient;
//添加
@Test
void contextLoads() {
Article article = new Article(1, "allen", "王武", "helloworld");
System.err.println(article);
//修改也可以用save
Index index = new Index.Builder(article)
.index("megacorp").type("news").build();
jestClient.execute(index);
}
//获取
@Test
public void search(){
//获取aaa索引中id为1的Article对象
String json = "";
Search search = new Search.Builder(json)
.addIndex("megacorp").addType("news").build();
SearchResult result = jestClient.execute(search );
}
2、SpringData ElasticSearch
注意:SpringData和ES版本需要适配
https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#preface.versions
(1)核心依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
(2)配置文件
spring.elasticsearch.rest.uris=192.168.99.100:9200
spring.data.elasticsearch.cluster-name=elasticsearch
spring.data.elasticsearch.cluster-nodes=192.168.99.100:9300
(3)实体类配置
@Data
@Document(indexName="megacorp", type="news")
public class Book{
@JestId
private Integer id;
private String author;
private String title;
(4)第一种调用:继承ElasticseanchRepository
public interface BookRepository
extends ElasticseanchRepository<Book,Integer> {
}
@Autowired
BookRepository bookRepository ;
//添加
@Test
void contextLoads() {
Book book = new Book();
bookRepository.index(book);
}
(5)第二种调用: ElasticsearchRestTemplate
@Autowired
ElasticsearchRestTemplate elasticsearchRestTemplate;
//添加
@Test
void contextLoads() {
Article article = new Article(1, "allen", "bbb", "helloworld");
System.err.println(article);
//修改也可以用save
elasticsearchRestTemplate.save(article);
}
//获取
@Test
public void test02(){
//获取aaa索引中id为1的Article对象
Article article = elasticsearchRestTemplate.get("1", Article.class);
System.out.println(article);
}