ElasticSearch01(ES简介,安装ES,操作索引,操作文档,RestAPI)【全详解】

目录

一、ES简介

1. 数据库查询的问题

2. ES简介

1 ElasticSearch简介

2 ElasticSearch发展

3. 倒排索引【面试】

1 正向索引

2 倒排索引

4. ES和MySql

5. 小结

二、安装ES

1. 方式1:使用docker安装

1 准备工作

2 创建ElasticSearch容器

3 给ElasticSearch配置ik分词器

4 创建Kibana容器

5 访问测试

2. 方式2:本机直接安装

1. 安装ES

2. 安装Kibana

3. 安装IK分词器

4. 安装过程中可能出现的问题

3. ik分词器

ES标准分词器的问题

IK分词器的使用示例

4. 小结

三、操作索引

1. ES的核心概念

2. 操作索引库

3. 小结

四、操作文档

1. 语法

2. 示例

3. 课堂演示

4. 动态映射

5. 小结

五、RestAPI

1. 准备工作

1 创建project导入依赖

2 创建实体类

3 RestAPI的使用说明

2. 操作索引【了解】

1 API说明

2 使用示例

3. 操作文档【重点】

1 API说明

2 使用示例

4. 批量操作文档

1 说明

2 示例

5. 小结

六、练习

需求

步骤

实现

1. 创建索引库

2. 准备环境

3. 批量插入数据

大总结


一、ES简介

1. 数据库查询的问题

select * from 商品信息表 where name like '%华为Mate60%'

可以搜索到:华为手机Mate60, 华为手机Mate60 Pro, 白色 华为手机Mate60

但是不能搜索:华为 手机Mate60

假如我们有一个电商系统,需要查询商品。以前一直是直接从MySql数据库里用SQL语句模糊查询,例如:

select * from tb_product where pname like '%华为手机%' 华为手机Mate 50 Pro 华为畅享手机

但是这种查询检索数据的方式,有很大的问题:

  • 查询性能很低

    MySql可以通过索引的方式来提高查询的效率,但是像上边这种模糊查询以%开头,会导致索引失效,实际上执行的是全表扫描,效率非常低。

  • 查询结果不准确

    我们应当查询到与“手机”、“华为”等词条相关的所有商品,而不是 只包含“华为手机”的商品

而这些问题,都可以使用ElasticSearch轻易的解决掉:把数据存储到ElasticSearch里,由ElasticSearch提供高效的文档检索能力

2. ES简介

1 ElasticSearch简介

ElasticSearch,简称ES。ES是一款非常强大的开源搜索引擎,可以帮助我们从海量数据中快速找到需要的内容。如百度搜索、京东商品搜索、打车软件中搜附近的车辆等等。

ES结合kibana、Logstash、Beats(也就是ELK技术栈,Elastic Stack),被广泛的用户在日志数据分析、实时监控等领域。ES是ELK的核心,负责存储、搜索、分析数据。

 

2 ElasticSearch发展

  • Doug Cutting于1999年研发了一个Java语言的搜索引擎类库(函数库):Lucene,目前已是Apache的顶级项目。

    官网地址:Apache Lucene - Welcome to Apache Lucene

    Lucene优势:易扩展、高性能(基于倒排索引)

    Lucene缺点:只限于Java语言、学习曲线陡峭、不支持水平扩展

  • 2004年Shay Banon基于Lucene开发了Compass,随后于2010年重写了Compass,取名为ElasticSearch。

    官网地址:Elasticsearch 平台 — 大规模查找实时答案 | Elastic

    相比于Lucene,ElasticSearch具备更多优势:

    1. 支持分布式,可水平扩展

    2. 提供RESTful接口(HTTP方式的请求),任何编程语言都可以使用。

  • 到目前为止,ElasticSearch已经成为主流的搜索引擎

3. 倒排索引【面试】

1 正向索引

说明

传统RDBMS(例如MySql)采用的是正向索引,即:根据表的主键字段构建索引,在查询时要扫描到每个索引值对应的数据,从中筛选出符合查询条件的记录。

这样的检索方式构建索引简单,但是不适合复杂的文档检索。复杂的文档检索时,索引会失效,变成全表扫描

示例

以商品表搜索为例,商品表tb_product如下:

 

要搜索包含“手机”的商品,执行SQL:select * from tb_product where title like '%华为手机%'

MySql会扫描所有的数据记录,逐条判断 “title”的值是否包含“手机”,直到全表扫描,过滤出所有符合要求的结果

  • 先找每条数据

  • 再判断每条数据是否符合要求

2 倒排索引

说明

ElasticSearch采用的是倒排索引,即:以字或词为关键字构建索引,保存每个关键字所在的记录。当需要查询时,根据词条匹配查询条件,直接找到关联的记录。

倒排索引的建立和维护都比较复杂,但是在查询时可以和查询关键字关联的所有结果,并快速响应。

示例

以商品表搜索为例,商品表略

构建倒排索引

文档Document:每条数据就是一个文档

词条term:按照语义分成的词语

当搜索“华为手机”时:

  1. 把搜索条件进行分词,得到两个词条:“华为”, “手机”

  2. 根据词条,去倒排索引里查询相关的文档id,得到:

    • “华为”:2, 3

    • “手机”:1, 2

  3. 根据文档id,找到对应的文档数据,得到:id为1、2、3的文档

4. ES和MySql

传统的RDBMS和ElasticSearch都可以增删改查,并且各有所长:

  • MySQL:擅长事务类操作,可以确保数据的一致性和安全性

  • ES:擅长海量数据的搜索、分析、计算

在实际开发中,通常是结合使用

  • MySQL负责写操作

  • ES负责搜索操作

5. 小结

 

ES是什么?是一个开源的搜索引擎,可以快速从海量数据里查找目标数据

ES为什么快?其中一个原因是,ES使用了倒排索引,避免了全表扫描,所以速度快

  • ES会对所有的数据,进行分词构建倒排表和倒排索引。 是词条对应文档的id集合

  • 当我们要搜索数据的时候,ES会先对搜索词进行分词,拿分词后的多个词条,直接去倒排索引里找到关联的文档id集合;从而找到关联的文档数据

ES和MySQL的对比:

  • 共同点:都具备增删改查的能力

  • 不同点:

    • MySQL擅长增删改 写操作。因为MySQL有事务,可以保证数据的一致性和完整性

    • ES擅长查询搜索。因为ES使用了倒排索引,可以快速从海量数据里查找目标数据

  • 实际开发中的应用:

    • 如果要增删改数据,找MySQL

    • 再把MySQL里的数据同步给ES

    • 我们再从ES里搜索查询数据

二、安装ES

1. 方式1:使用docker安装

1 准备工作

首先把《es7.4.0.tar》和《kibana7.4.0.tar》上传到CentOS的/root目录里

然后执行以下命令:

#创建文件夹。用于挂载到ElasticSearch容器上
mkdir -p /data/elasticsearch/config
mkdir -p /data/elasticsearch/data

#创建es配置文件,设置允许任意主机访问ElasticSearch
echo "http.host: 0.0.0.0" >> /data/elasticsearch/config/elasticsearch.yml

#设置文件夹的权限
chmod -R 777 /data/elasticsearch

2 创建ElasticSearch容器

#创建ElasticSearch容器并启动
docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms512m -Xmx512m" \
-v /data/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /data/elasticsearch/data:/usr/share/elasticsearch/data \
-v /data/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
-d elasticsearch:7.4.0

#如果想要查看ElasticSearch是否启动成功,可以打开浏览器访问  http://ip地址:9200

3 给ElasticSearch配置ik分词器

可以之前去输入拉取镜像的命令,这里是直接加载准备好的包

把ik分词器插件文件夹上传到 CentOS的/data/elasticsearch/plubins文件夹里,重启ElasticSearch容器

重启es

 #重启ElasticSearch
 docker restart elasticsearch

4 创建Kibana容器

注意:一定要把命令里的ip地址,修改成ElasticSearch的访问ip

#安装Kibana:注意一定要把ip地址设置为ElasticSearch的ip
docker run --name kibana -e ELASTICSEARCH_HOSTS=http://192.168.200.130:9200 -p 5601:5601 \
 -d kibana:7.4.0
 

5 访问测试

打开浏览器访问:http://192.168.200.130:5601 如果能正常打开,说明已经完全启动成功了

注意:ElasticSearch和Kibana的启动,都需要花费一定时间,如果浏览器页面打不开,就耐心等待一会

2. 方式2:本机直接安装

1. 安装ES

目前我们安装的是ES的7.4.0版本,需要JDK8及以上

准备工作:Cpolar关闭或者卸载,因为它占用了9200端口。这个端口是ES使用的

关闭Cpolar的方式:

  • 打开“服务”窗口,找到Cpolar Service

  • 在服务上右键停止;

  • 在服务上右键-属性-启动类型,修改为“手动”;确定并关闭

  • 打开浏览器,输入地址 http://localhost:9200

    • 如果显示出来了一个登录页面,就按 ctrl + shift + delete,清除浏览器缓存

    • 再刷新页面,保证页面是不能访问的。(不能访问,说明Cpolar已经成功关闭了)

1 解压

把《elasticsearch-7.4.0-windows-x86_64.zip》解压到一个不含中文、空格、特殊字符的目录里

 

2 配置

1) 配置存储路径

打开config/elasticsearch.yml文件,设置索引数据的存储路径,和日志的存储路径

 

2) 配置虚拟机参数

 

3 启动

进入es的bin目录,直接双击 elasticsearch.bat即可启动

es服务要占用两个端口:

  • 9200:rest访问接口,我们稍后要通过这个端口连接es、操作es

  • 9300:用于es集群间通信的接口

4 验证

在浏览器上直接输入地址 http://localhost:9200/, 如果看到以下界面,说明es启动成功了

 

 

2. 安装Kibana

Kibana是一个ES索引库数据统计工具,可以利用ES的聚合功能,生成各种图表,如柱形图,线状图,饼图等。

而且还提供了操作ES索引数据的控制台,并且提供了一定的API提示,非常有利于我们学习ES的语法。

1 安装nodeJs

Kibana依赖于nodeJs,需要在windows下先安装Node.js,然后才能安装Kibana。

双击nodejs的安装包,按照提示一步步安装即可

安装成功后,打开cmd 输入:node -v,如果能看到版本号,说明node安装成功

2 安装Kibana

docker pull kibana:7.4.0   拉取kibana镜像,可以直接拉取

1) 解压

把《kibana-7.4.0-windows-x86_64.zip》解压到不含中文、空格、特殊字符的目录里

 

2) 配置

修改kibana的config/kibana.yml,配置es的地址

3) 启动

进入到kibana的bin目录,双击 kibana.bat 启动。启动稍微有些慢,耐心等待一会

 

4) 访问

打开浏览器输入 http://localhost:5601/

 

 

3. 安装IK分词器

1 ES标准分词器的问题

ES自带的分词器叫“Standard Analyzer”,它对中文的支持非常不友好,会将一个词语的每个字拆分成一个词条,和中文的语法是完全不符的。

例如,一个词语“黑马程序员”,按中文语法习惯可以拆分成“黑马”,“程序员”,“程序”等词条。但是标准分词器分拆分成“黑”,“马”,“程”,“序”,“员”

示例如下:

2 安装IK分词器

为了解决中文词语拆分的问题,可以安装一个IK分词器。IK分词器是一款适合于中文分词习惯的、优秀的中文分词器,具有60万字/秒的高速处理能力。

它支持两种粒度的拆分:

  • ik_smart:做粗粒度的拆分

  • ik_max_word:将文本做细粒度的拆分,拆分出尽可能多的词条(建议用这种)

1) 解压

把分词器《elasticsearch-analysis-ik-7.4.0.zip》解压到es的plugins目录下,重命名为“ik”

2) 重启

  1. 重启es

  2. 重启kibana

3) 测试

在浏览器的kibana开发工具界面,输入并执行

 

 

4. 安装过程中可能出现的问题

1 JDK环境变量问题

现象:启动ES时,黑窗口一闪而过

可能的原因:ElasticSearch7.4,要求使用jdk8或者jdk11。如果JDK版本不正确,启动es会报错(可能是JDK环境变量有问题)

验证方式:打开cmd,执行java -version,看一下JDK版本;再执行javac -version,看一下版本号

2 端口占用问题

现象:启动ES时,黑窗口运行着运行着就关了

可能的原因:苍穹外卖里内网穿透软件cpolar,占用的是9200端口,会导致使用es出问题

解决方式:

  • 方式一:关掉cpolar服务或者卸载cpolar,然后重启电脑,再启动es,就没有端口冲突了。es会占用9200端口

    关闭cpolar的方式:Windows+R,运行 services.msc,找到 Cpolar 服务,右键停止;然后右键属性,启动方式修改为手动

  • 方式二:不管它,es发现9200被占用,它会自动改用其它端口。要看一下启动es的控制台,看它的端口是多少 (一般是9201)。

    然后Kibana要配置连接ES时的地址,配置成 http://localhost:9201

3 操作系统权限问题

你的电脑当前用户权限不足,会导致启动es和Kibana会报错 “operate not promitted...”。解决方法是:

es文件夹和Kibana文件夹都需要设置:

  • 在文件夹上右键-属性-安全-编辑-添加

  • 在弹出的容器里,添加当前计算机用户名(可以在cmd里使用 net user 查看)

勾选中这个用户,点击下边的“完全控制”,再确定

3. ik分词器

ES标准分词器的问题

ES自带的分词器叫“Standard Analyzer”,它对中文的支持非常不友好,会将一个词语的每个字拆分成一个词条,和中文的语法是完全不符的。

例如,一个词语“黑马程序员”,按中文语法习惯可以拆分成“黑马”,“程序员”,“程序”等词条。但是标准分词器分拆分成“黑”,“马”,“程”,“序”,“员”

示例如下:

IK分词器的使用示例

在浏览器的kibana开发工具界面,输入并执行

 

 

 

4. 小结

ES于客户端连接

安装ElasticSearch

  1. 准备工作

    先把镜像文件上传到Linux里。加载镜像文件:docker load -i 文件名

    准备文件夹和配置文件,稍后要用于跟es容器进行挂载

  2. 创建es容器。

  3. 把ik分词器上传到Linux里

  4. 创建Kibana容器

分词器:

  • es自带标准分词器:standard分词器,对中文分词效果不好

  • ik分词器:对中文分词效果好。分词粒度有:

    ik_smart:智能分词

    ik_max_word:尽可能拆分出更多的词条

三、操作索引

ES我们通常不用java去创建索引库,一般直接在kibana直接几行直接搞定

1. ES的核心概念

  • 老版本(es7之前)结构:

Indices----->Type---->document----->field

Database-->Table--->row-------------->column

  • 从es7开始,抛弃了type的概念:

Index(索引库)-->Document(json文档)-->Field(json里的key)

Table------------->Row------------------------->column

 

2. 操作索引库

1 索引库映射mapping(类似MySql的表结构)

说明

映射mapping:目的是为了给索引的每个Field设置类型(字符串,数字,日期,对象,数组……)

在MySql里,我们在插入一条记录之前,需要提前设置好表里每个每个字段的类型。

而类似的,在ES里,我们需要给每个索引库设置映射信息

参考:Put mapping API | Elasticsearch Guide [7.4] | Elastic

映射类型

每个字段field要设置的 常见的maping属性有:

  • type:字段的类型,常见的简单类型有

    • text:可分词的文本字符串。如果是text,需要设置analyzer分词器

    • keyword:不分词的文本字符串。某些字符串一旦分词就失去意义了,例如品牌、国家、ip地址、url地址等

    • byte,short,integer,long,double,float等数值

    • boolean

    • date日期。ES可以把日期格式化为字符串存储,但是为了节省空间,建议使用long存储毫秒值

    • object对象。如果是object,需要设置properties

  • index:是否创建索引,默认true。如果字段值不参与搜索,要设置为false。比如图片url

  • analyzer:使用哪种分词器。text类型时需要设置,其它类型的字段不需要设置

  • properties:字段的子字段。如果字段是object时,需要设置子字段

示例

有如下文档数据,分析该索引库的mapping映射

{
    "age": 21,                          integer
    "weight": 52.1,                     double
    "isMarried": false,                 boolean
    "info": "黑马程序员Java讲师",         text,要分词;analyzer分词器
    "email": "zy@itcast.cn",            keyword, 不分词
    "score": [99.1, 99.5, 98.9],        double
    "name": {                           object
        "firstName": "云",
        "lastName": "赵"
    },
    "avatar": "http://www.xx.com/xxx.jpg"   keyword, index:false
}

2 索引库的CURD

1 语法

  • 创建索引库

PUT /索引库名
{
    "mappings":{
        "properties":{
            "字段名":{
                "type": "类型",
                "index": true,
                "analyzer": "分词器",
                ...
            },
            "字段名":{
                "type": "类型",
                "index": true,
                "analyzer": "分词器",
                ...
            },
            ...
        }
    }
}

  • 查看索引库

    查看所有索引库:GET /_cat/indices

    查看某个索引库:GET /索引库名

  • 修改索引库

    注意:es里不能修改已有字段,可以给索引库添加字段

    因为创建好索引库后,es会构建倒排索引,这个过程是比较消耗性能的。一旦索引库的某个字段被修改,可能会导致原本的倒排索引失效,影响太大,所以es不能修改索引库中已有的字段。

PUT /索引库名/_mapping
{
    "properties":{
        "新字段名":{
            "type": "类型",
            "index": true,
            ...
        },
        "新字段名":{
            "type": "类型",
            "index": true,
            ...
        },
        ...
    }
}

删除索引库:DELETE /索引库名

2 示例

要求:创建一个索引库,用于存储黑马讲师的信息

#1. 创建索引(相当于创建一张表)
PUT /heima
{
  "mappings": {
    "properties": {
      "age":{
        "type": "integer"
      },
      "weight":{
        "type": "double"
      },
      "isMarried":{
        "type": "boolean"
      },
      "info":{
        "type": "text",
        "analyzer": "ik_smart"
      },
      "email":{
        "type": "keyword",
        "index": false
      },
      "score":{
        "type": "double",
        "index": false
      },
      "name":{
        "type": "object",
        "properties": {
          "firstName":{
            "type":"keyword"
          },
          "lastName":{
            "type":"keyword"
          }
        }
      }
    }
  }
}

#2. 查看索引
GET /heima
#    查看所有索引
GET /_cat/indices?v

#3. 修改索引:给索引添加字段
PUT /heima/_mapping
{
  "properties":{
    "address":{
      "type": "keyword"
    }
  }
}

#删除heima索引库
DELETE /heima

3 课堂演示

#创建一个索引库(相当于建表)
PUT /product
{
  "mappings": {
    "properties": {
      "name":{
        "type": "text",
        "analyzer": "ik_max_word"
      },
      "price":{
        "type": "integer"
      },
      "stock":{
        "type": "integer"
      },
      "image":{
        "type": "keyword",
        "index": false
      }
    }
  }
}
#查看索引库
# 查看某个索引库  GET /索引库名
GET /product
# 查看所有索引库  GET /_cat/indices
GET /_cat/indices
#修改索引库。
#  注意:不能修改已有字段,只能增加新字段
PUT /product/_mapping
{
  "properties":{
    "category":{
      "type": "keyword"
    }
  }
}
#删除索引库  DELETE /索引库名
DELETE /product

3 练习

要求1:创建一个索引库itcast,用于存储商品信息。要有以下字段:

  • 商品id id

  • 商品名称 title

  • 商品价格 price

  • 所属品牌 brand

  • 商品库存量 quantity

  • 商品图片url地址 images

要求2:查看索引库itcast的信息

要求3:给索引库itcast增加一个字段“商品分类 category”

要求4:删除索引库itcast

#练习:
# 1. 创建索引库
PUT /itcast
{
  "mappings": {
    "properties": {
      "id":{
        "type": "integer"
      },
      "title":{
        "type": "text",
        "analyzer": "ik_smart"
      },
      "price":{
        "type": "double"
      },
      "brand":{
        "type": "keyword"
      },
      "quantity":{
        "type": "integer"
      },
      "images":{
        "type": "keyword",
        "index": false
      }
    }
  }
}
#2. 查询索引库
GET /_cat/indices
GET /itcast
#3. 增加一个字段
PUT /itcast/_mapping
{
  "properties":{
    "category":{
      "type": "keyword"
    }
  }
}
#. 删除索引库
DELETE /itcast

3. 小结

ES的几个概念:

  • Index:索引。相当于MySQL里的表

  • Document:文档。相当于MySQL表里的一行数据。只不过是json格式

  • Field:字段。相当于MySQL表里的字段

  • Mapping:映射。相当于MySQL表的结构,包括有哪些字段、字段的类型、约束等等

索引的映射结构:创建索引时,每个字段需要设置

  • type类型:

    • 字符串有2种

      text:如果字段值是字符串,并且要分词,就使用text。如果是text,就必须给这个字段设置analyzer

      keyword:如果字段值是字符串,并且不分词,就使用keyword

    • 数字类型:byte, short, integer, long, double, float等等

    • 布尔类型:boolean

    • 日期类型:date

    • 对象类型:object

  • index是否参与搜索:如果某个字段的值,不需要根据这个字段搜索数据,就给字段设置index值为false

  • analyzer:分词器。如果字段类型是text的时候,必须设置分词器。

    standard 标准分词器

    ik_smart ik智能分词

    ik_max_word ik细粒度的分词

操作ES索引的语法:

#创建索引
PUT /索引库名
{
    "mappings":{
        "properties":{
            "字段名":{
                "type": 类型,
                "index": 是否参与搜索 如果不参与搜索 设置为false,
                "analyzer": 分词器 如果类型是text就必须设置分词器 通常用ik_smart或ik_max_word
            },
            "字段名":{
                "type": 类型,
                "index": 是否参与搜索 如果不参与搜索 设置为false,
                "analyzer": 分词器 如果类型是text就必须设置分词器 通常用ik_smart或ik_max_word
            },
            "字段名":{
                "type": 类型,
                "index": 是否参与搜索 如果不参与搜索 设置为false,
                "analyzer": 分词器 如果类型是text就必须设置分词器 通常用ik_smart或ik_max_word
            },
            ....
        }
    }
}

#查看索引库
#    查看某一名称的索引库结构
GET /索引库
#    查看所有索引库
GET /_cat/indices

#修改索引。不能修改已有字段,只能 增加新字段
PUT /索引库名/_mapping
{
    "properties":{
        "字段名":{
            "type": 类型,
            "index": 是否参与搜索 如果不参与搜索 设置为false,
            "analyzer": 分词器 如果类型是text就必须设置分词器 通常用ik_smart或ik_max_word
        },
        ....
    }
}
#删除索引
DELETE /索引库名

四、操作文档

本章节学习目标:

  • 掌握文档的CURD

1. 语法

参考:Document APIs | Elasticsearch Guide [7.4] | Elastic

  • 新增与修改文档

    如果文档id不存在:是新增文档

    如果文档id已存在:是修改文档,会直接覆盖掉原文档

PUT /索引库名/_doc/文档id
{
    "key": value,
    ...
    "key": value
}

  • 查看文档:GET /索引库名/_doc/id

  • 修改文档:增量修改。

    在原文档基础上进行修改某些字段的值

POST /索引库名/_update/文档id
{
    "doc":{
        "字段1": 值1,
        "字段2": 值2,
        ...
    }
}

删除文档:DELETE /索引库名/_doc/id值

2. 示例

#1. 新增文档
PUT /itcast/_doc/1
{
  "title":"小米手机",
  "price":4999,
  "brand":"小米",
  "images":"http://www.mi.com/mi8.jpg"
}

#2. 查看文档
GET /itcast/_doc/1

#3. 修改文档
#   全量修改,相当于使用新文档把旧文档替换掉了
PUT /itcast/_doc/1
{
  "price": 9999
}
#   增量修改,在原本文档基础上做修改
POST /itcast/_update/1
{
  "doc": {
    "price":9999
  }
}

#4. 删除文档
DELETE /itcast/_doc/1

3. 课堂演示

#-----文档的CURD-------------
#先准备一个索引(先准备一张表)
DELETE /product
PUT /product
{
  "mappings": {
    "properties": {
      "id":{
        "type": "long"
      },
      "name":{
        "type": "text",
        "analyzer": "ik_max_word"
      },
      "price":{
        "type": "integer"
      },
      "stock":{
        "type": "integer"
      },
      "image":{
        "type": "keyword",
        "index": false
      }
    }
  }
}
#新增一条文档数据
PUT /product/_doc/1
{
  "id":100,
  "name":"华为Pura70",
  "price":7999,
  "stock":100,
  "image": "http://www.huawei.com/p70.jpg"
}
#查询id为1的文档
GET /product/_doc/1
#修改文档:增量修改,即在原有数据的基础上做变化-用的少
POST /product/_update/1
{
  "doc":{
    "stock":1000
  }
}
#修改文档:覆盖式修改,使用新数据直接覆盖原数据-用的多
PUT /product/_doc/1
{
  "name":"华为Pura70",
  "price":7999,
  "image": "http://www.huawei.com/p70.jpg"
}
#删除文档:
DELETE /product/_doc/1
#查询列表
POST /product/_search

4. 动态映射

思考

如果新增文档的结构,与mapping结构不一致,会出现什么结果

例如

#插入的文档结构,与mapping结构不符。itcast索引库中原本没有color、weight、stock、isSoldOut四个字段
PUT /itcast/_doc/2
{
  "title": "罗技鼠标",
  "price": 89,
  "images": "http://www.jd.com/xxxx.jpg",
  "quantity": 50,
  "weight": 0.22,
  "color": "black",
  "isSoldOut": false
}

查询索引的映射:GET /itcast/_mapping

看到结果

{
  "itcast" : {
    "mappings" : {
      "properties" : {
        "color" : { #增加了color字段,是字符串。ES无法判断类型,因此存储了两种映射类型。color是text类型,color.keyword是keyword类型
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "images" : {
          "type" : "keyword",
          "index" : false
        },
        "isSoldOut" : { #增加了isSoldOut字段,类型boolean
          "type" : "boolean"
        },
        "price" : {
          "type" : "double"
        },
        "quantity" : {
          "type" : "integer"
        },
        "title" : {
          "type" : "text",
          "analyzer" : "ik_smart"
        },
        "weight" : { #增加了weight字段,类型float
          "type" : "float"
        }
      }
    }
  }
}

说明

插入文档时,es会检查文档中的字段是否有对应的mapping,如果没有,则按照默认的mapping规则来创建索引。

如果默认的mapping不符合你的要求,一定要自己设置字段的mapping

5. 小结

#新增一条文档。如果唯一标识对应的文档不存在,是新增。如果已存在,会覆盖掉
PUT /索引/_doc/唯一标识
{
    "字段":值,
    "字段":值,
    ...
}
#查看一条文档
GET /索引/_doc/唯一标识
#修改一条文档:增量修改,即在原本文档基础上做变更
POST /索引/_update/唯一标签
{
    "doc":{
        "字段":值,
        "字段":值,
        ...
    }
}
#修改一条文档:覆盖式修改,直接拿新的json文档,把旧的json文档覆盖掉
PUT /索引/_doc/唯一标识
{
    "字段":值,
    "字段":值,
    ...
}
#删除一条文档
DELETE /索引/_doc/唯一标识

#查询列表
POST /product/_search

五、RestAPI

1. 准备工作

官方文档:Compatibility | Java REST Client [7.4] | Elastic

1 创建project导入依赖

导入es的客户端依赖坐标

注意:es客户端依赖的版本号,必须要和es的版本号一致

<dependencies>
    <!--es客户端-->
    <dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>elasticsearch-rest-high-level-client</artifactId>
        <version>7.4.0</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>5.8.2</version>
    </dependency>

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.70</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.24</version>
    </dependency>
</dependencies>

2 创建实体类

商品Product,对应es里的product索引

package com.itheima.domain;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Product {
    private Long id;
    /**标题*/
    private String title;
    /**分类*/
    private String category;
    /**品牌*/
    private String brand;
    /**价格*/
    private Double price;
    /**图片地址*/
    private String images;
}

3 RestAPI的使用说明

要想操作es,需要按照如下步骤:

  1. 创建RestHighLevelClient对象

  2. 使用RestHighLevelClient操作es

  3. 关闭RestHighLevelClient

//1. 创建RestHighLevelClient客户端对象。
//   如果连接ES集群,就写多个地址;
//   如果是单ES实例,就只写一个地址
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(
    new HttpHost("localhost", 9200)
));

//2. 使用client操作es

//3. 关闭client
client.close();

2. 操作索引【了解】

1 API说明

RestHighLevelClient对象提供了操作索引库的API方法,常用的有:

  • 创建:restClient.indices().create(CreateIndexRequest request, RequestOptions options)

  • 删除:restClient.indices().delete(DeleteIndexRequest request, RequestOptions options)

  • 是否存在:restClient.indices().exists(GetIndexRequest request, RequestOptions options)

以上方法的参数:

  • CreateIndexRequest:创建索引库的请求对象

  • DeleteIndexRequest:删除索引库的请求对象

  • GetIndexRequest:查询索引库的请求对象

  • RequestOptions:创建索引库的请求选项,使用固定值RequestOptions.DEFAULT即可

注意事项:

  • 使用RestAPI创建索引库非常繁琐,建议在Kibana里使用DSL语句执行操作,而不是用Java代码创建索引库

2 使用示例

索引库分析

要把一条商品信息存储到es,我们要先分析一下对应的索引库及映射该如何编写:

  • id: 商品id,可以使用long类型

  • title:商品名称,使用text类型,要分词并构建倒排索引进行搜索

  • category:商品分类,分类是整体,不进行分词,使用keyword

  • brand:品牌,和分类类似,不进行分词,使用keyword

  • price:价格,double类型

  • images:图片地址,用来展示的字段,不需要构建索引,不参与搜索;index设置为false,使用keyword类型

编辑DSL命令如下:

DELETE /product
PUT /product
{
    "mappings":{
        "properties":{
            "id":{
                "type": "long"
            },
            "title":{
                "type": "text",
                "analyzer": "ik_max_word"
            },
            "category":{
                "type": "keyword"
            },
            "brand":{
                "type": "keyword"
            },
            "price":{
                "type": "double"
            },
            "images":{
                "type": "keyword",
                "index": false
            }
        }
    }
}

操作示例

使用RestHighLevelClient操作的示例代码如下:

package com.itheima;import org.apache.http.HttpHost;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;import java.io.IOException;public class Demo01Index {private RestHighLevelClient client;/*** 创建索引库*/@Testpublic void testCreateIndex() throws IOException {String json = "{\n" +"  \"mappings\": {\n" +"    \"properties\": {\n" +"      \"id\": {\n" +"        \"type\": \"long\"\n" +"      },\n" +"      \"title\": {\n" +"        \"type\": \"text\",\n" +"        \"analyzer\": \"ik_max_word\"\n" +"      },\n" +"      \"category\": {\n" +"        \"type\": \"keyword\"\n" +"      },\n" +"      \"brand\": {\n" +"        \"type\": \"keyword\"\n" +"      },\n" +"      \"price\": {\n" +"        \"type\": \"double\"\n" +"      },\n" +"      \"images\": {\n" +"        \"type\": \"keyword\",\n" +"        \"index\": false\n" +"      }\n" +"    }\n" +"  }\n" +"}";CreateIndexRequest request = new CreateIndexRequest("itheima").source(json, XContentType.JSON);client.indices().create(request, RequestOptions.DEFAULT);}/*** 删除索引库*/@Testpublic void testDeleteIndex() throws IOException {DeleteIndexRequest request = new DeleteIndexRequest("itheima");client.indices().delete(request, RequestOptions.DEFAULT);}/*** 索引库是否存在*/@Testpublic void testExistsIndex() throws IOException {GetIndexRequest request = new GetIndexRequest("itheima");boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);System.out.println(exists);}@BeforeEachpublic void init(){client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200)));}@AfterEachpublic void destroy() throws IOException {client.close();}
}

3. 操作文档【重点】

1 API说明

使用Java操作文档,和在kibana里编写DSl非常类似。只是由Java代码来执行相同的操作

RestHighLevelClient提供了操作文档的API如下:

  • 新增与修改:client.index(IndexRequest request, RequestOptions options)

  • 查看:client.get(GetRequest request, RequestOptions options)

  • 删除:client.delete(DeleteRequest request, RequestOptions options)

以上方法的参数:

  • IndexRequest:新增与修改文档的请求对象

  • GetRequest:查询文档的请求对象

  • DeleteRequest:删除文档的请求对象

  • RequestOptions:请求选项参数,使用固定值RequestOptions.DEFAULT即可

2 使用示例

package com.itheima;import com.alibaba.fastjson.JSON;
import com.itheima.pojo.Product;
import org.apache.http.HttpHost;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;import java.io.IOException;public class Demo02Document {RestHighLevelClient client = null;/*** 保存文档* 如果id不存在,是新增* 如果id已存在,是修改*/@Testpublic void testSaveDocument() throws IOException {Product product = new Product(1L, "华为 Mate40 pro", "手机数码", "华为", 5200D, "http://images.huawei.com/pro40.jpg");String productJson = JSON.toJSONString(product);//1. 准备Request对象,设置索引库名称IndexRequest indexRequest = new IndexRequest("product")//设置文档id.id(product.getId().toString())//设置文档数据.source(productJson, XContentType.JSON);//2. 发送请求client.index(indexRequest, RequestOptions.DEFAULT);}/*** 查看文档*/@Testpublic void testFindDocument() throws IOException {//1. 准备RequestGetRequest getRequest = new GetRequest("product", "1");//2. 发送请求GetResponse response = client.get(getRequest, RequestOptions.DEFAULT);//3. 处理响应结果String docJson = response.getSourceAsString();Product product = JSON.parseObject(docJson, Product.class);System.out.println(product);}/*** 删除文档*/@Testpublic void testDeleteDocument() throws IOException {//1. 准备RequestDeleteRequest deleteRequest = new DeleteRequest("product", "1");//2. 发送请求client.delete(deleteRequest, RequestOptions.DEFAULT);}@BeforeEachpublic void init() {client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200)));}@AfterEachpublic void destroy() throws IOException {client.close();}
}

4. 批量操作文档

1 说明

批量操作的核心在于将多个普通请求封装在一个批量请求中,一次性发送到服务器,下面仅仅演示批量新增(其他自己尝试)

操作的步骤:

  1. 准备BulkRequest对象

  2. 把每个文档数据,封装到一个IndexRequest对象里。把IndexRequest添加到BulkRequest对象中

  3. 使用client.bulk(bulkRequest对象, RequestOptions.DEFAULT)

2 示例

/*** 批量操作文档*/
@Test
public void testBulkDocument() throws IOException {//0. 模拟数据List<Product> list = new ArrayList<Product>();list.add(new Product(11L, "小米手机", "手机数码", "小米", 3299.00, "http://image.huawei.com/13123.jpg"));list.add(new Product(12L, "锤子手机", "手机数码", "锤子", 3699.00, "http://image.huawei.com/13123.jpg"));list.add(new Product(13L, "联想手机", "手机数码", "联想", 4499.00, "http://image.huawei.com/13123.jpg"));list.add(new Product(14L, "红米手机", "手机数码", "小米", 4299.00, "http://image.huawei.com/13123.jpg"));list.add(new Product(15L, "iPhone X", "手机数码", "苹果", 8299.00, "http://image.huawei.com/13123.jpg"));list.add(new Product(16L, "MacBook pro", "电脑", "苹果", 14999.00, "http://image.huawei.com/13123.jpg"));list.add(new Product(17L, "AirPods", "手机数码", "苹果", 4299.00, "http://image.huawei.com/13123.jpg"));list.add(new Product(18L, "外星人", "电脑", "DELL", 21299.00, "http://image.huawei.com/13123.jpg"));list.add(new Product(19L, "联想小新", "电脑", "联想", 6299.00, "http://image.huawei.com/13123.jpg"));//1. 创建RequestBulkRequest bulkRequest = new BulkRequest();//2. 添加数据for (Product product : list) {//2.1 把一个Product对象,封装到一个IndexRequest对象里IndexRequest indexRequest = new IndexRequest("product").id(product.getId().toString());indexRequest.source(JSON.toJSONString(product), XContentType.JSON);//2.2 把一个IndexRequest对象添加到BulkRequest对象里bulkRequest.add(indexRequest);}//3. 发送请求client.bulk(bulkRequest, RequestOptions.DEFAULT);
}

5. 小结

使用Java操作ES,准备工作:

  1. 添加依赖坐标:关键是elasticsearch-rest-high-level-client。我们提供的工程里已经有了,不需要额外再添加

  2. 修改配置文件:没有 跟es相关的配置,但是为了防止启动连接数据库不存在,先执行SQL脚本

  3. 把客户端连接对象放到IoC容器里。把以下代码加到引导类里,或者加到一个配置类里

@Bean
public RestHighLevelClient esClient(){
    return new RestHighLevelClient(RestClient.builder(
        new HttpHost("192.168.200.130", 9200)
    ));
}

     4. 创建单元测试类,添加@SpringBootTest,再注入RestHighLevelClient对象

操作索引的API

//1. 创建索引
CreateIndexRequest request = new CreateIndexRequest("索引名").source("json字符串", XContentType.JSON);
esClient.indices().create(request, RequestOptions.DEFAULT);//2. 删除索引
DeleteIndexRequest request = new DeleteIndexRequest("索引名");
esClient.indices().delete(request, RequestOptions.DEFAULT);//3. 判断索引是否存在
GetIndexRequest request = new GetIndexRequest("索引名")
boolean exists = esClient.indices().exists(request, RequestOptions.DEFAULT);

操作文档的API

//1. 新增或修改
IndexRequest request = new IndexReuqest("索引名").id("文档唯一标识").source("文档json字符串", XContentType.JSON);
esClient.index(request, RequestOptions.DEFAULT);//2. 查询
GetRequset request = new GetRequest("索引名").id("文档唯一标识");
GetResponse response = esClient.get(request, RequestOptions.DEFAULT);
String docJson = response.getSourceAsString();//3. 删除
DeleteRequest request = new DeleteRequest("索引名").id("文档唯一标识");
esClient.delete(request, RequestOptions.DEFAULT);//4. 批量操作:通常用于批量新增,也可以用于批量删除等写操作
BulkRequest bulkRequest = new BulkRequest("索引名");
for(Xxx xx: list){//准备IndexRequest对象IndexRequest request = new IndexRequest().id(xx.getId().toString()).source(JSON.toJSONString(xx), XContentType.JSON);//把IndexRequest添加到BulkRequest对象里bulkRequest.add(request);
}
//最后一次性把BulkRequest里的数据存储到es里
esClient.bulk(bulkRequest, RequestOption.DEFAULT);

六、练习

需求

执行SQL脚本《资料/tb_hotel.sql》,其中有tb_hotel表,存储了酒店的数据

利用BulkRequest批量将数据库数据导入到索引库中。

步骤

  1. 根据数据库表结构,在es里创建对应的索引库

  2. 使用Java程序读取MySQL数据,再使用RestHighLevelClient存储到es的索引库里

实现

1. 创建索引库

使用Kibana执行DSL语句创建索引库,DSL语句如下:

# 创建酒店索引
PUT /hotel
{
  "mappings": {
    "properties": {
      "id":{
        "type": "long"
      },
      "name":{
        "type": "text",
        "analyzer": "ik_max_word",
        "copy_to": "all"
      },
      "address":{
        "type": "text",
        "analyzer": "ik_smart",
        "copy_to": "all"
      },
      "price":{
        "type": "integer"
      },
      "score":{
        "type": "integer"
      },
      "brand":{
        "type": "keyword",
        "copy_to": "all"
      },
      "city":{
        "type": "keyword",
        "copy_to": "all"
      },
      "starName":{
        "type": "keyword"
      },
      "business":{
        "type": "keyword",
        "copy_to": "all"
      },
      "location":{
        "type": "geo_point"
      },
      "pic":{
        "type": "keyword",
        "index": false
      },
      "all":{
        "type": "text",
        "analyzer": "ik_max_word"
      }
    }
  }
}

2. 准备环境

创建一个新的project,执行以下步骤:

导入依赖

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.9.RELEASE</version>
</parent>

<!--全局锁定ES客户端的版本号-->
<properties>
    <elasticsearch.version>7.4.0</elasticsearch.version>
</properties>

<dependencies>
    <!--es客户端-->
    <dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>elasticsearch-rest-high-level-client</artifactId>
    </dependency>
    <!-- web起步依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- mp和mysql -->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.4.0</version>
    </dependency>
    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
        <version>8.0.33</version>
    </dependency>

    <!-- 单元测试 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>

    <!-- json转换 -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.70</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
</dependencies>

配置文件

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql:///es
    username: root
    password: root

引导类

@SpringBootApplication
@MapperScan("com.itheima.mapper")
public class HotelApplication {
    public static void main(String[] args) {
        SpringApplication.run(HotelApplication.class, args);
    }
}

实体类Hotel

对应MySQL的tb_hotel表

package com.itheima.pojo;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;@Data
@TableName("tb_hotel")
public class Hotel {@TableId(type = IdType.AUTO)private Long id;private String name;private String address;private Integer price;private Integer score;private String brand;private String city;private String starName;private String business;private String longitude;private String latitude;private String pic;
}

实体类HotelDoc

对应ES的文档数据

package com.itheima.pojo;import lombok.Data;
import lombok.NoArgsConstructor;@Data
@NoArgsConstructor
public class HotelDoc {private Long id;private String name;private String address;private Integer price;private Integer score;private String brand;private String city;private String starName;private String business;private String location;private String pic;public HotelDoc(Hotel hotel) {this.id = hotel.getId();this.name = hotel.getName();this.address = hotel.getAddress();this.price = hotel.getPrice();this.score = hotel.getScore();this.brand = hotel.getBrand();this.city = hotel.getCity();this.starName = hotel.getStarName();this.business = hotel.getBusiness();this.location = hotel.getLatitude() + ", " + hotel.getLongitude();this.pic = hotel.getPic();}
}

HotelMapper

public interface HotelMapper extends BaseMapper<Hotel> {
}

3. 批量插入数据

package com.itheima;import com.alibaba.fastjson.JSON;
import com.itheima.mapper.HotelMapper;
import com.itheima.pojo.Hotel;
import com.itheima.pojo.HotelDoc;
import org.apache.http.HttpHost;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.io.IOException;
import java.util.List;@SpringBootTest
public class HotelTest {@Autowiredprivate HotelMapper hotelMapper;@Testpublic void test() throws IOException {RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200)));//1. 读取数据库里所有的酒店数据List<Hotel> list = hotelMapper.selectList(null);//2. 循环酒店列表,把每个酒店数据添加到BulkRequest对象里BulkRequest bulkRequest = new BulkRequest();for (Hotel hotel : list) {//把每个Hotel对象转换成对应ES的HotelDoc对象HotelDoc doc = new HotelDoc(hotel);//创建IndexRequest对象IndexRequest request = new IndexRequest("hotel").id(doc.getId().toString()).source(JSON.toJSONString(doc), XContentType.JSON);bulkRequest.add(request);}//3. 执行批量插入client.bulk(bulkRequest, RequestOptions.DEFAULT);//4. 关闭连接client.close();}
}

总结

大总结

ES是什么?是一个开源的搜索引擎,可以从海量数据里快速找到目标数据

ES为什么快?其中有一个原因就是使用了倒排索引

  • 正向索引:找到一条数据记录,判断是否符合条件。可能会出现全表扫描

  • 倒排索引:直接根据搜索条件,定位到符合条件的文档数据。不会有全表扫描,性能更高

ES和MySQL(关系型数据库)的对比

  • 共同点:都可以增删改查数据

  • 不同点:

    MySQL或其它关系型数据库:擅长事务型的操作,增删改,因为有严谨的事务保证数据的一致性和完整性

    ES搜索:擅长查询检索,因为ES有倒排索引,更适合于从海量数据里快速查询检索数据。特别是文本字符串的模糊匹配

  • 实际使用时:两者配合使用

    如果需要增删改数据,要操作MySQL

    然后把MySQL里的数据同步到ES里

    然后再从ES里查询检索数据

ES相关的几个概念:

  • Index:索引。相当于MySQL里的表

  • Mapping:映射。相当于MySQL里的表结构。即表里有什么字段、字段是什么类型、字段有什么其它限制约束等等

  • Field:字段。相当于MySQL表里的字段

  • Document:文档。是json格式的,相当于MySQL里的一行数据记录

  • DSL:用于操作ES的命令语法,相当于操作关系型数据库的SQL语句

DSL命令操作索引

#创建索引
PUT /索引名
{
    "mappings":{
        "properties":{
            "字段名":{
                "type": 类型, #类型常用的有:text,keyword,byte,short,integer,long,double,float, boolean, date, geo_point
                "index": 是否参与搜索,
                "analyzer": 分词器 如果类型是text,就需要设置分词器 #ik_smart, ik_max_word
            },
            ....
        }
    }
}
#查询所有索引
GET /_cat/indices
#查看某一索引
GET /索引
#修改索引:不能修改已有字段,只能增加新字段
PUT /索引/_mapping
{
    "properties":{
        "字段名":{
            "type": 类型, #类型常用的有:text,keyword,byte,short,integer,long,double,float, boolean, date, geo_point
            "index": 是否参与搜索,
            "analyzer": 分词器 如果类型是text,就需要设置分词器 #ik_smart, ik_max_word
        },
        ....    
    }
}
#删除索引
DELETE /索引

DSL命令操作文档

#新增文档(覆盖式修改索引)
PUT /索引/_doc/唯一标识
{
    "字段": 值,
    "字段": 值,
    ...
}
#查看某一文档
GET /索引/_doc/唯一标识
#查看文档列表
POST /索引/_search
#增量修改
POST /索引/_update/唯一标识
{
    "doc":{
        "字段": 值,
        "字段": 值,
           ...
    }
}
#删除文档
DELETE /索引/_doc/唯一标识

Java操作索引

  • 先添加依赖坐标:elasticsearch-rest-high-level-client

  • 把RestHighLevelClient对象放到IoC容器里:在配置类里或者在引导类里添加

@Bean
public RestHighLevelClient esClient(){
    return new RestHighLevelClient(RestClient.builder(
        new HttpHost("ip地址", 端口)
    ));
}

操作索引的Api

esClient.indices().create(CreateIndexRequest request, RequestOptions options);
esClient.indices().delete(DeleteIndexRequest request, RequestOptions options);
esClient.indices().exists(GetIndexRequest request, RequestOptions options);

Java操作文档

esClient.index(IndexRequest request, RequestOptions options);
GetResponse response = esClient.get(GetRequest request, RequestOptions options);
esClient.delete(DeleteRequest request, RequestOptions options);

esClient.bulk(BulkRequest request, RequestOptions options);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/318721.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

有限单元法-编程与软件应用(崔济东、沈雪龙)【PDF下载】

专栏导读 作者简介&#xff1a;工学博士&#xff0c;高级工程师&#xff0c;专注于工业软件算法研究本文已收录于专栏&#xff1a;《有限元编程从入门到精通》本专栏旨在提供 1.以案例的形式讲解各类有限元问题的程序实现&#xff0c;并提供所有案例完整源码&#xff1b;2.单元…

vue2项目webpack3.x打包文件分割优化加载

vue2项目webpack3.x打包文件分割优化加载 0. 项目目录和依赖信息1. 开启 gzip&#xff08;建议&#xff09;2. vue2项目配置懒加载&#xff08;建议&#xff09;3. 拆分 vendor 包注意&#xff1a;webpack3使用CommonsChunkPlugin实现 本文使用 3 种方案进行叠加优化 优先级按以…

postman一直转圈圈,无法启动

解决 地址栏输入%appdata%进入此目录&#xff0c;删除%appdata%目录下的postman文件可以解决问题。

node.js中path模块-路径处理,语法讲解

node中的path 模块是node.js的基础语法&#xff0c;实际开发中&#xff0c;我们通过使用 path 模块来得到绝对路径&#xff0c;避免因为相对路径带来的找不到资源的问题。 具体来说&#xff1a;Node.js 执行 JS 代码时&#xff0c;代码中的路径都是以终端所在文件夹出发查找相…

未来科技的前沿:深入探讨人工智能的进展、机器学习技术和未来趋势

文章目录 一、人工智能的定义和概述1. 人工智能的基本概念2. 人工智能的发展历史 二、技术深入&#xff1a;机器学习、深度学习和神经网络1. 机器学习2. 深度学习3. 神经网络 三、人工智能的主要目标和功能1. 自动化和效率提升2. 决策支持和风险管理3. 个性化服务和预测未来 本…

SpringBoot中实现发送邮件

概要 在Spring Boot中发送电子邮件相对简单。你可以使用Spring的邮件支持来实现这一点。 步骤&#xff1a; 1.添加依赖&#xff1a;首先&#xff0c;需要在你的pom.xml文件中添加Spring Boot的邮件发送器依赖。 2. 配置邮件服务器&#xff1a;在application.properties或app…

网络相关知识总结

1、网口设置 网口设置IP&#xff0c;即操作/etc/sysconfig/network-scripts路径下的ifcfg-xx文件 主要参数详解&#xff1a; DEVICE:网口名 ONBOOT&#xff1a;表示启动系统时是否激活网卡&#xff0c;yes为激活&#xff0c;no不激活 HWADDR:mac值 DEFROUTE://默认路由设置…

RTMP 直播推流 Demo(一)—— 项目配置与视频预览

音视频编解码系列目录&#xff1a; Android 音视频基础知识 Android 音视频播放器 Demo&#xff08;一&#xff09;—— 视频解码与渲染 Android 音视频播放器 Demo&#xff08;二&#xff09;—— 音频解码与音视频同步 RTMP 直播推流 Demo&#xff08;一&#xff09;—— 项目…

linux 服务器利用阿里网盘API实现文件的上传和下载

文章目录 背景脚本初始化 阿里云盘API工具 aligo安装aligoaligo教程实战parse.py 演示上传文件上传文件夹下载文件下载文件夹 背景 最近在用ubuntu系统做实验&#xff0c;而ubuntu 系统的文件上传和下载操作很麻烦&#xff1b; 于是便打算使用阿里网盘的API 进行文件下载与上传…

Docker - 修改服务的端口

1. 测试 新建一个httpd服务 docker run -itd -p 1314:80 --name test -h test httpd 2. 先停止容器和 docke r服务 docker stop test #停止容器3. 修改配置 cd /var/lib/docker/containers ls 找到需要修改的 cd 1fc55f0d24014217cff68c9a417ca46cf50312caa5c9e6bb24085126…

为什么 IP 地址通常以 192.168 开头?(精简版)

网络通讯的本质就是收发数据包。如果说收发数据包就跟收发快递一样。IP地址就类似于快递上填的收件地址和发件地址一样&#xff0c;路由器就充当快递员的角色&#xff0c;在这个纷繁复杂的网络世界里找到该由谁来接收这个数据包&#xff0c;所以说&#xff1a;IP地址就像快递里…

django搭建一个AI博客进行YouTube视频自动生成文字博客

文章目录 一、生成Django框架二、项目代码&#xff08;前端&#xff09;1、编写前端代码&#xff08;正文界面&#xff09;1.1、生产html框架1.2、添加live preview扩展1.3、更改title元素中文本1.4、添加CDN&#xff08;CSS&#xff09;样式链接1.5、nav标签1.6、在body标签中…

OpenCV(三)—— 车牌筛选

本篇文章要介绍如何对从候选车牌中选出最终进行字符识别的车牌。 无论是通过 Sobel 还是 HSV 计算出的候选车牌都可能不止一个&#xff0c;需要对它们进行评分&#xff0c;选出最终要进行识别的车牌。这个过程中会用到两个理论知识&#xff1a;支持向量机和 HOG 特征。 1、支…

华为机考入门python3--(19)牛客19- 简单错误记录

分类&#xff1a;字符串 知识点&#xff1a; 分割字符串 my_str.split(\\) 字符串只保留最后16位字符 my_str[-16:] 列表可以作为队列、栈 添加元素到第一个位置 my_list.insert(0, elem) 增加元素到最后一个位置 my_list.append(elem) 删除第一个 my_list.pop(0)…

C/C++开发环境配置

配置C/C开发环境 1.下载和配置MinGW-w64 编译器套件 下载地址&#xff1a;https://sourceforge.net/projects/mingw-w64/files/mingw-w64/mingw-w64-release/ 下载后解压并放至你容易管理的路径下&#xff08;我是将其放在了D盘的一个software的文件中管理&#xff09; 2.…

奈氏准则和香农定理

一、奈奎斯特和香农 哈里奈奎斯特&#xff08;Harry Nyquist&#xff09;(左) 克劳德艾尔伍德香农&#xff08;Claude Elwood Shannon&#xff09;(右) 我们应该在心里记住他们&#xff0c;记住所有为人类伟大事业做出贡献的人&#xff0c;因为他们我们的生活变得越来越精彩&…

【UnityRPG游戏制作】NPC交互逻辑、动玩法

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;就业…

多级留言/评论的功能实现——SpringBoot3后端篇

目录 功能描述数据库表设计后端接口设计实体类entity 完整实体类dto 封装请求数据dto 封装分页请求数据vo 请求返回数据 Controller控制层Service层接口实现类 Mapper层Mybatis 操作数据库 补充&#xff1a;返回的数据结构自动创建实体类 最近毕设做完了&#xff0c;开始来梳理…

✔ ★Java大项目——用Java模拟RabbitMQ实现一个消息队列(二)【创建核心类、封装数据库操作】

✔ ★Java大项目——用Java模拟RabbitMQ实现一个消息队列 四. 项⽬创建五. 创建核⼼类 ★创建 Exchange&#xff08;名字、类型、持久化、自动删除、参数&#xff09;创建 MSGQueue&#xff08;名字、持久化、独占标识&#xff09;创建 Binding&#xff08;交换机名字、队列名字…

UDP编程流程(UDP客户端、服务器互发消息流程)

一、UDP编程流程 1.1、 UDP概述 UDP&#xff0c;即用户数据报协议&#xff0c;是一种面向无连接的传输层协议。相比于TCP协议&#xff0c;UDP具有以下特点&#xff1a; 速度较快&#xff1a;由于UDP不需要建立连接和进行复杂的握手过程&#xff0c;因此在传输数据时速度稍快…