赞
踩
本博客为个人学习笔记,学习网站:黑马程序员SpringCloud 2021教程
目录
mapping是对索引库中文档的约束,常见的mapping属性包括:
1. type:字段数据类型,常见的简单类型有:
字符串:text(可分词的文本)、keyword(精确值,例如:品牌、国家、ip地址、分词无意义的值)
数值:long、integer、short、byte、double、float
布尔:boolean
日期:date
对象:object
2. index:是否创建索引,默认为true
3. analyzer:使用哪种分词器
4. properties:该字段的子字段
示例 :
按以下json文档的字段创建一个索引库
- {
- "age": 21,
- "weight": 52.1,
- "isMarried": false,
- "info": "黑马程序员Java讲师",
- "email": "zy@itcast.cn",
- "score": [99.1, 99.5, 98.9],
- "name": {
- "firstName": "云",
- "lastName": "赵"
- }
- }
创建索引库DSL语句如下
- # 创建索引库
- PUT /heima
- {
- "mappings": {
- "properties": {
- "info":{
- "type": "text",
- "analyzer": "ik_smart"
- },
- "email":{
- "type": "keyword",
- "index": false
- },
- "name":{
- "type": "object",
- "properties": {
- "firstName":{
- "type": "keyword"
- },
- "lastName":{
- "type":"keyword"
- }
- }
- }
- }
- }
- }
如果在查询文档时,想要同时基于多个字段进行查询,那么在创建索引库时,可以把这些字段通过"copy_to"拷贝到另外一个字段all中,在之后的搜索中,直接搜索all字段即可。而且,all字段在查询得到的结果文档中是不会显示出来的,但是在查询的时候,会提示可以查询all字段。
查询索引库:
- #语法
- GET /索引库名
-
- #示例如下
- GET /heima
删除索引库:
- #语法如下
- DELETE /索引库名
-
- #示例如下
- DELETE /heima
修改索引库:
倒排索引结构虽然不复杂,但是一旦数据结构改变(比如改变了分词器),就需要重新创建倒排索引,这简直是灾难。因此索引库一旦创建,就无法修改mapping。虽然无法修改mapping中已有的字段,但是却允许添加新的字段到mapping中,因为这样不会对倒排索引产生影响。
新增字段:
- #语法如下
- PUT /索引库名/_mapping
- {
- "properties": {
- "新字段名":{
- "type": "integer"
- }
- }
- }
-
- #示例如下(新字段名必须和存在的字段名不同)
- PUT /heima/_mapping
- {
- "properties":{
- "age":{
- "type":"long"
- }
- }
- }
- #语法如下
- POST /索引库名/_doc/文档id
- {
- "字段1": "值1",
- "字段2": "值2",
- "字段3": {
- "子属性1": "值3",
- "子属性2": "值4"
- },
- // ...
- }
-
- #示例如下
- POST /heima/_doc/1
- {
- "info": "黑马程序员Java讲师",
- "email": "zy@itcast.cn",
- "name": {
- "firstName": "云",
- "lastName": "赵"
- }
- }
查询文档:
- #语法如下
- GET /{索引库名称}/_doc/{id}
-
- #示例如下
- GET /heima/_doc/1
删除文档:
- #语法如下
- DELETE /{索引库名}/_doc/id值
-
- #示例如下(根据id删除文档)
- DELETE /heima/_doc/1
修改文档有两种方式:
1. 全量修改:直接覆盖原来的文档
2. 增量修改:修改文档中的部分字段
全量修改是覆盖原来的文档,其本质是:先根据指定的id删除文档,再新增一个相同id的文档
注意:如果根据id删除时,id不存在,第二步的新增也会执行,也就从修改变成了新增操作了。
- #语法如下
- PUT /{索引库名}/_doc/文档id
- {
- "字段1": "值1",
- "字段2": "值2",
- // ... 略
- }
-
- #示例如下
- PUT /heima/_doc/1
- {
- "info": "黑马程序员高级Java讲师",
- "email": "zy@itcast.cn",
- "name": {
- "firstName": "云",
- "lastName": "赵"
- }
- }
增量修改是只修改指定id匹配的文档中的部分字段。
- #语法如下
- POST /{索引库名}/_update/文档id
- {
- "doc": {
- "字段名": "新的值",
- }
- }
-
- #示例如下
- POST /heima/_update/1
- {
- "doc": {
- "email": "ZhaoYun@itcast.cn"
- }
- }
创建文档:POST/(索引库名}/_doc/文档id {json文档}
查询文档:GET /(索引库名}/_doc/文档id
删除文档:DELETE /(索引库名}/_doc/文档id
修改文档:
全量修改:PUT /(索引库名}/doc/文档id {json文档 }
增量修改:POST/{索引库名}/_update/文档id {“doc":{字段}}
在elasticsearch提供的API中,与elasticsearch一切交互都封装在一个名为RestHighLevelClient的类中,必须先完成这个对象的初始化,建立与elasticsearch的连接。
步骤1. 引入es的RestHighLevelClient依赖:
- <dependency>
- <groupId>org.elasticsearch.client</groupId>
- <artifactId>elasticsearch-rest-high-level-client</artifactId>
- </dependency>
步骤2. 因为SpringBoot默认的ES版本是7.6.2,所以我们需要覆盖默认的ES版本:
- <properties>
- <java.version>1.8</java.version>
- <elasticsearch.version>7.12.1</elasticsearch.version>
- </properties>
步骤3. 初始化RestHighLevelClient,代码如下:
- RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(
- HttpHost.create("http://192.168.150.101:9200")
- ));
步骤4. 这里为了单元测试方便,我们创建一个测试类HotelIndexTest,然后将初始化的代码编写在@BeforeEach方法中:
- package cn.itcast.hotel;
-
- import org.apache.http.HttpHost;
- import org.elasticsearch.client.RestHighLevelClient;
- import org.junit.jupiter.api.AfterEach;
- import org.junit.jupiter.api.BeforeEach;
- import org.junit.jupiter.api.Test;
-
- import java.io.IOException;
-
- public class HotelIndexTest {
- private RestHighLevelClient client;
-
- @BeforeEach
- void setUp() {
- this.client = new RestHighLevelClient(RestClient.builder(
- HttpHost.create("http://192.168.150.101:9200")
- ));
- }
-
- @AfterEach
- void tearDown() throws IOException {
- this.client.close();
- }
- }
代码如下:
- @Test
- void createHotelIndex() throws IOException {
- // 1.创建Request对象
- CreateIndexRequest request = new CreateIndexRequest("hotel");
- // 2.准备请求的参数:DSL语句
- request.source(MAPPING_TEMPLATE, XContentType.JSON);
- // 3.发送请求
- client.indices().create(request, RequestOptions.DEFAULT);
- }
- @Test
- void testDeleteHotelIndex() throws IOException {
- // 1.创建Request对象
- DeleteIndexRequest request = new DeleteIndexRequest("hotel");
- // 2.发送请求
- client.indices().delete(request, RequestOptions.DEFAULT);
- }
- @Test
- void testExistsHotelIndex() throws IOException {
- // 1.创建Request对象
- GetIndexRequest request = new GetIndexRequest("hotel");
- // 2.发送请求
- boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
- // 3.输出
- System.err.println(exists ? "索引库已经存在!" : "索引库不存在!");
- }
我们需要将数据库的酒店数据查询出来,写入elasticsearch中。而数据库查询后得到的结果是一个Hotel类型的对象。结构如下:
- @Data
- @TableName("tb_hotel")
- public class Hotel {
- @TableId(type = IdType.INPUT)
- 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;
- }
由于该对象的结构与elasticsearch索引库结构存在差异,因此我们需要定义一个新的类型,与索引库结构吻合,结构如下:
- package cn.itcast.hotel.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();
- }
- }
新增文档语法:
从数据库中查询数据,并新增到ES文档实现:
- @Test
- void testAddDocument() throws IOException {
- // 1.根据id查询酒店数据
- Hotel hotel = hotelService.getById(61083L);
- // 2.转换为文档类型
- HotelDoc hotelDoc = new HotelDoc(hotel);
- // 3.将HotelDoc转json
- String json = JSON.toJSONString(hotelDoc);
-
- // 1.准备Request对象
- IndexRequest request = new IndexRequest("hotel").id(hotelDoc.getId().toString());
- // 2.准备Json文档
- request.source(json, XContentType.JSON);
- // 3.发送请求
- client.index(request, RequestOptions.DEFAULT);
- }
查询语法:
代码如下:
- @Test
- void testGetDocumentById() throws IOException {
- // 1.准备Request
- GetRequest request = new GetRequest("hotel", "61082");
- // 2.发送请求,得到响应
- GetResponse response = client.get(request, RequestOptions.DEFAULT);
- // 3.解析响应结果
- String json = response.getSourceAsString();
-
- HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
- System.out.println(hotelDoc);
- }
在DSL语法中,我们讲过修改文档的两种方式:
1. 全量修改:本质是先根据id删除,再新增
2. 增量修改:修改文档中的指定字段值
在Restclient的API中,全量修改与新增的API完全一致,判断依据是ID:
如果新增时,ID已存在,则修改;
如果新增时,ID不存在,则新增。
全量修改的语法这里不再赘述,参考前面的新增文档即可,这里我们主要关注增量修改。
增量修改语法如下:
代码如下:
- @Test
- void testUpdateDocument() throws IOException {
- // 1.准备Request
- UpdateRequest request = new UpdateRequest("hotel", "61083");
- // 2.准备请求参数
- request.doc(
- "price", "952",
- "starName", "四钻"
- );
- // 3.发送请求
- client.update(request, RequestOptions.DEFAULT);
- }
根据id删除文档,代码如下:
- @Test
- void testDeleteDocument() throws IOException {
- // 1.准备Request
- DeleteRequest request = new DeleteRequest("hotel", "61083");
- // 2.发送请求
- client.delete(request, RequestOptions.DEFAULT);
- }
利用BulkRequest实现批量操作,其本质就是将多个普通的CRUD请求组合在一起发送。
其中提供了一个add方法,我们可以把IndexRequest(新增)、UpdateRequest(修改)、DeleteRequest(删除) 通过add方法进行添加,从而实现批量操作。
示例:
利用MP从数据库获取数据,并批量新增完整代码:
- @Test
- void testBulkRequest() throws IOException {
- // 批量查询酒店数据
- List<Hotel> hotels = hotelService.list();
-
- // 1.创建Request
- BulkRequest request = new BulkRequest();
- // 2.准备参数,添加多个新增的Request
- for (Hotel hotel : hotels) {
- // 2.1.转换为文档类型HotelDoc
- HotelDoc hotelDoc = new HotelDoc(hotel);
- // 2.2.创建新增文档的Request对象
- request.add(new IndexRequest("hotel")
- .id(hotelDoc.getId().toString())
- .source(JSON.toJSONString(hotelDoc), XContentType.JSON));
- }
- // 3.发送请求
- client.bulk(request, RequestOptions.DEFAULT);
- }
文档操作的基本步骤:
1. 初始化RestHighLevelClient
2. 创建XxxRequest。XXX是Index、Get、Update、Delete、Bulk
3. 准备参数(Index、Update、Bulk时需要)
4. 发送请求。调用RestHighLevelClient#.xxx()方法,xx是index、get、update、delete、bulk
5. 解析结果(Get时需要)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。