分布式搜索引擎elasticsearch_1

一、了解elasticsearch?

1,elasticsearch的作用

​ elasticsearch是一款非常强大的开源搜索引擎,具备非常多强大的功能,可以帮助我们在海量数据中快速搜索想要的内容。

​ 同时支持分页与高亮显示。

2,ELK技术栈

​ elastic stack(ELK)是elasticsearch结合kibana、Logstash的技术栈。

​ 其中,elasticsearch是elastic stack的核心,负责存储、搜索、分析数据。

​ Kibana负责数据可视化,Logstash、Beats负责数据抓取

在这里插入图片描述

3,elasticsearch和lucene

  • lucene:

    • Lucene是一个Java语言的搜索引擎类库,是Apache公司的顶级项目,由DougCutting于1999年研 发。官网地址:https://lucene.apache.org/ 。
    • lucene是elasticsearch的底层。
    • 优势:
      • 易扩展
      • 高性能(基于倒排搜索
    • 缺点:
      • 只限于java语言开发(因为他是基于java语言的类库)
      • 不利于水平扩展
  • elasticsearch:

    • elasticsearch是基于lucene实现的,但是它改变了lucene的缺点
      • 提供Restful接口,可被任意语言调用
      • 支持分布式,可水平扩展

二、正向索引与倒排索引

1,正向索引

在这里插入图片描述

以上图为例,为表的【id】字段创建索引。

  1. 如果是根据【id】查询,可以直接走索引,查询速度非常快。
  2. 但是如果是基于【title】做模糊查询,只能逐条搜索,如上图右边。
    • 逐条搜索,也就是全表搜索,一旦数据到达一定的量级(如百万条),简直就是灾难。
    • 为此,出现了一种新的搜索方式,倒排索引

即便为title建立索引,数据库模糊匹配,索引不生效。

2,倒排搜索

倒排搜索中的相关概念:

  • 文档(Document):用来搜索的数据,其中的每一条数据就是一个文档。例如一个网页、一个商品信息

  • 词条(Term):对文档数据或用户搜索数据,利用某种算法分词,得到的具备含义的词语就是词条。

​ 例如:小米手机充电器,就可以分为:小米、手机、充电器等

2.1,创建倒排索引

​ 创建倒排索引是对正向索引的一种特殊处理,图示如下:

在这里插入图片描述

左边的表是数据库数据导入es后的索引库的文档。

创建的词条表放在es中,获取文档id后在文档中查询想要的数据。

  1. 如对【title】进行处理。
  2. 将每条文档数据利用算法分词,得到一个个词条。
  3. 数据库每条数据就是一个文档。
  4. 创建词条表,每行数据包括词条、词条所在的文档【id】、位置等信息

并将对应的数据存入词条表

  1. 因为词条具有唯一性,可以给词条创建索引

创建过程:

1,将【小米手机】分为【小米、手机】

2,在词条表的词条列创建【小米】,并在文档id列填写【1】

3,在词条表的词条列创建【手机】,并在文档id列填写【1】

4,将【华为手机】分为【华为、手机】

5,在词条表的词条列创建【华为】,并在文档id列填写【1】

6,因为词条里面已经有【手机】,在该行的文档id列添加【2】,数据变成【1,2】

2.2,倒排搜索流程
  • 图解:

    • 虽然经过了两次搜索,但两次都带索引,所以搜索速度并不慢。

在这里插入图片描述

3,正向与倒排

  • 正向索引是最传统的,根据id索引的方式。但根据词条查询时,必须先逐条获取每个文档,然后判断文档中是否包含所需要的词条,是根据文档找词条的过程

  • 倒排索引则相反,是先找到用户要搜索的词条,根据词条得到保护词条的文档的id,然后根据id获取文档。是根据词条找文档的过程

  • 正向索引

    • 优点:
      • 可以给多个字段创建索引
      • 根据索引字段搜索、排序速度非常快
    • 缺点:
      • 根据非索引字段,或者索引字段中的部分词条查找时,只能全表扫描。

    倒排索引

    • 优点:
      • 根据词条搜索、模糊搜索时,速度非常快
    • 缺点:
      • 只能给词条创建索引,而不是字段
      • 无法根据字段做排序

三、ES相关概念

在elasticsearch7以后,type已经没有了。

1,文档与字段

elasticsearch是面向**文档(Document)**存储的,一个文档中可以包含多个字段。

在这里插入图片描述

2,索引与映射

  • 相同类型放在一起就是索引,类似于数据库的表。
  • 映射类似于数据库表的约束信息,如字段唯一,类型为varcher等

在这里插入图片描述

3,mysql与elasticsearch

mysql与elasticsearch的概念做一下对比:

MySQLElasticsearch说明
TableIndex索引(index),就是文档的集合,类似数据库的表(table)
RowDocument文档(Document),就是一条条的数据,类似数据库中的行(Row),文档都是JSON格式
ColumnField字段(Field),就是JSON文档中的字段,类似数据库中的列(Column)
SchemaMappingMapping(映射)是索引中文档的约束,例如字段类型约束。类似数据库的表结构(Schema)
SQLDSLDSL是elasticsearch提供的JSON风格的请求语句,用来操作elasticsearch,实现CRUD

两者各自有自己的擅长支出:

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

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

所以一般而言,MySQL于ES配合使用,写操作时使用MySQL,读操作时使用ES。

二者之间通过一定的方式实现数据同步。

在这里插入图片描述

四、安装elasticsearch,Kibana,ik分词器

​ 单独文档。

五、索引库操作

1,概述

​ 索引库顾名思义就是存储文档的仓库,类似于数据库的表。

​ 只不过数据库的表存储的是一行行数据,索引库存储的是一个个文档。

2,mappings

  • mappings:映射,相当于数据库表对字段的约束条件。
    • type:字段数据类型,常见的简单类型有:
      • 字符串:text(可分词的文本)、keyword(精确值,例如:品牌、国家、ip地址)
      • 数值:long、integer、short、byte、double、float、
      • 布尔:boolean
      • 日期:date
      • 对象:object
    • index:是否创建索引,默认为true
    • analyzer:使用哪种分词器
    • properties:该字段的子字段
    • store:是否存储

text类型需要分词,keyword类型不需要分词。

index、store默认值为true

  • 见下面的例子
{
    "age": 21,
    "weight": 52.1,
    "isMarried": false,
    "info": "黑马程序员Java讲师",
    "email": "zy@itcast.cn",
    "score": [99.1, 99.5, 98.9],
    "name": {
        "firstName": "云",
        "lastName": "赵"
    }
}

对应的每个字段映射(mapping):

  • age:类型为 integer;参与搜索,因此需要index为true;无需分词器
  • weight:类型为float;参与搜索,因此需要index为true;无需分词器
  • isMarried:类型为boolean;参与搜索,因此需要index为true;无需分词器
  • info:类型为字符串,需要分词,因此是text;参与搜索,因此需要index为true;分词器可以用ik_smart
  • email:类型为字符串,但是不需要分词,因此是keyword;不参与搜索,因此需要index为false;无需分词器
  • score:虽然是数组,但是我们只看元素的类型,类型为float;参与搜索,因此需要index为true;无需分词器
  • name:类型为object,需要定义多个子属性
    • name.firstName;类型为字符串,但是不需要分词,因此是keyword;参与搜索,因此需要index为true;无需分词器
    • name.lastName;类型为字符串,但是不需要分词,因此是keyword;参与搜索,因此需要index为true;无需分词器

3,创建索引库

# 模板
put /【索引库名称】
{
    "mappings": {
    "properties": {
      "【字段名】":{
        "【类型】": "text",
        "【分词类型】": "ik_smart",
          ......
      },
      "【字段名】":{
        ......
      },
      ......
}



#创建索引库
PUT /heima
{
  "mappings": {
    "properties": {
      "info":{
        "type": "text",
        "analyzer": "ik_smart",
        "index": true,
        "store": true
      },
      "email":{
        "type": "text",
        "analyzer": "ik_max_word"
      },
      "brand":{
        "type": "keyword"
      },
      "name":{
        "properties": {
          "firstName":{
            "type":"keyword"
          },
          "lastName":{
            "type":"keyword"
          }
        }
      },
      "birth":{
        "type": "date",
        "format": "yyyy-MM-dd"
      }
    }
  }
}

4,修改索引库

​ 索引库的修改只能增加字段

# 模板
PUT /【索引名】/_mapping
{
  "properties": {
    "新字段名":{
      "":""
    }
  }
}

5,查询索引库

# 模板
GET /【索引库名】

# 查询索引
GET /heima

6,删除索引库

#模板
DELETE /【索引库名】

#删除索引
DELETE /heima

六、文档操作

1,增加文档

# 模板
POST /【索引库名】/_doc/【文档id,建议自定义,不定义会自动生成】

# 增加文档
POST /heima/_doc/1
{
  "birth":"1999-10-01",
  "brand":"星辰",
  "email":"yuming@xc.cn",
  "info":"太阳,月亮,都是星辰",
  "name":{
    "firstName":"鱼",
    "lastName":"星辰"
  }
}

2,查看文档

#模板
GET /【索引库名】/_doc/【文档id】

#查看文档
GET /heima/_doc/1

3,修改文档

#修改文档_增量修改(局部修改)
POST /heima/_update/1
{
  "doc": {
    "brand":"星辰",
    "email":"yuming@xcy.cn"
  }
}


#修改文档_全局修改
PUT /heima/_doc/1
{
  "birth":"1999-10-01",
  "brand":"星辰啊",
  "email":"yuming@xc.cn",
  "info":"太阳,月亮,都是星辰",
  "name":{
    "firstName":"鱼",
    "lastName":"星辰"
  }
}

4,删除文档

# 删除文档
# DELETE /索引名【自己创建的索引的名称】/_doc【表示操作的是文档】/1【文档id,表示存在id为1的文档】
DELETE /heima/_doc/1

七、使用java操作elasticsearch

1,准备工作

  • 导入依赖

    <dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>elasticsearch-rest-high-level-client</artifactId>
    </dependency>
    
  • 修改上面依赖的版本

    因为依赖需要于elasticsearch版本相同,elasticsearch、kibana的版本也要一样

    <properties>
        <elasticsearch.version>7.12.1</elasticsearch.version>
    </properties>
    
  • 在配置类配置RestHighLevelClient

    • EsConstant.HOST【elasticsearch的ip(“192.168.138.100”)】
    • EsConstant.PORT【elasticsearch的端口(9200)】
    @Configuration
    public class EsConfig {
    
        @Bean
        public RestHighLevelClient restHighLevelClient(){
            return new RestHighLevelClient(
                    RestClient.builder(new HttpHost(EsConstant.HOST, EsConstant.PORT))
            );
        }
    
    }
    

2,创建索引库

​ 创建索引库需要索引库的名称,以及索引库的样式。

// 索引库的名称
public static final String HOTEL_INDEX = "hotel";

// 索引库的样式
public static final String SOURCE = "{\n" +
        "  \"mappings\": {\n" +
        "    \"properties\": {\n" +
        "      \"id\":{\n" +
        "        \"type\": \"keyword\"\n" +
        "      },\n" +
        "      \"name\":{\n" +
        "        \"type\":\"text\",\n" +
        "        \"analyzer\": \"ik_max_word\",\n" +
        "        \"copy_to\": \"all\"\n" +
        "      },\n" +
        "      \"address\":{\n" +
        "        \"type\": \"text\",\n" +
        "        \"analyzer\": \"ik_max_word\",\n" +
        "        \"copy_to\": \"all\"\n" +
        "      },\n" +
        "      \"price\":{\n" +
        "        \"type\": \"integer\"\n" +
        "      },\n" +
        "      \"score\":{\n" +
        "        \"type\": \"integer\"\n" +
        "      },\n" +
        "      \"brand\":{\n" +
        "        \"type\": \"keyword\",\n" +
        "        \"copy_to\": \"all\"\n" +
        "      },\n" +
        "      \"city\":{\n" +
        "        \"type\": \"keyword\",\n" +
        "        \"copy_to\": \"all\"\n" +
        "      },\n" +
        "      \"starName\":{\n" +
        "        \"type\": \"keyword\"\n" +
        "      },\n" +
        "      \"business\":{\n" +
        "        \"type\": \"text\",\n" +
        "        \"analyzer\": \"ik_max_word\",\n" +
        "        \"copy_to\": \"all\"\n" +
        "      },\n" +
        "      \"location\":{\n" +
        "        \"type\": \"geo_point\"\n" +
        "      },\n" +
        "      \"pic\":{\n" +
        "        \"type\": \"keyword\",\n" +
        "        \"index\": false\n" +
        "      },\n" +
        "      \"all\":{\n" +
        "        \"type\": \"text\",\n" +
        "        \"analyzer\": \"ik_max_word\"\n" +
        "      }\n" +
        "    }\n" +
        "  }\n" +
        "}";
  • 注意

    • 使用source导入索引库的样式包括索引库的大括号

      image-20230519200856217

    • 使用mapping的话只需要mappings后面 {} 里内容,包括{}

@Autowired
private RestHighLevelClient restHighLevelClient;

/**
 * 创建索引库
 */
@Test
public void createTest() throws IOException {
    CreateIndexRequest createIndexRequest = 
            new CreateIndexRequest(EsConstant.HOTEL_INDEX);
    // 如果使用mapping,EsConstant.SOURCE只需要
    createIndexRequest.source(EsConstant.SOURCE, XContentType.JSON);
    restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
}

3,查询索引库

@Autowired
private RestHighLevelClient restHighLevelClient;

/**
 * 查询索引库
 */
@Test
public void getTest() throws IOException {
    // EsConstant.HOTEL_INDEX 索引库名称
    GetIndexRequest getIndexRequest = new GetIndexRequest(EsConstant.HOTEL_INDEX);
    GetIndexResponse response = restHighLevelClient
            .indices()
            .get(getIndexRequest, RequestOptions.DEFAULT);
    Collection<MappingMetadata> values = response.getMappings().values();
}

4,判断索引库是否存在

@Autowired
private RestHighLevelClient restHighLevelClient; 

/**
  * 判断索引库算法存在
  */
 @Test
 public void existTest() throws IOException {
     // EsConstant.HOTEL_INDEX 索引库名称
     GetIndexRequest getIndexRequest = new GetIndexRequest(EsConstant.HOTEL_INDEX);
     boolean exists = restHighLevelClient
             .indices()
             .exists(getIndexRequest, RequestOptions.DEFAULT);
     System.out.println(exists);
 }

5,删除索引库

@Autowired
private RestHighLevelClient restHighLevelClient; 

/**
 * 删除索引库
 */
@Test
public void deleteTest() throws IOException {
    // EsConstant.HOTEL_INDEX 被删除的索引库名称
    DeleteIndexRequest deleteIndexRequest = new 				DeleteIndexRequest(EsConstant.HOTEL_INDEX);
    AcknowledgedResponse response = restHighLevelClient
            .indices()
            .delete(deleteIndexRequest, RequestOptions.DEFAULT);
    System.out.println("response.isAcknowledged() = " + response.isAcknowledged());
}

6,完整代码

package cn.itcast.hotel;

import cn.itcast.hotel.constant.EsConstant;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.GetIndexResponse;
import org.elasticsearch.cluster.metadata.MappingMetadata;
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.Collection;

/**
 * @author 星辰鱼
 * @version 1.0
 * @date 2023/5/19 16:05
 */
@SpringBootTest
public class TestHotel {

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    /**
     * 判断索引库算法存在
     */
    @Test
    public void existTest() throws IOException {
        GetIndexRequest getIndexRequest = new GetIndexRequest(EsConstant.HOTEL_INDEX);
        boolean exists = restHighLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
        System.out.println(exists);
    }

    /**
     * 查询索引库
     */
    @Test
    public void getTest() throws IOException {
        GetIndexRequest getIndexRequest = new GetIndexRequest(EsConstant.HOTEL_INDEX);
        GetIndexResponse response = restHighLevelClient.indices().get(getIndexRequest, RequestOptions.DEFAULT);
        Collection<MappingMetadata> values = response.getMappings().values();
        System.out.println(values);
    }

    /**
     * 创建索引库
     */
    @Test
    public void createTest() throws IOException {
        CreateIndexRequest createIndexRequest = new CreateIndexRequest(EsConstant.HOTEL_INDEX);
        // 如果使用mapping,EsConstant.SOURCE只需要
        createIndexRequest.source(EsConstant.SOURCE, XContentType.JSON);
        restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
    }

    /**
     * 删除索引库
     */
    @Test
    public void deleteTest() throws IOException {
        // EsConstant.HOTEL_INDEX:被删除的索引库名称
        DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(EsConstant.HOTEL_INDEX);
        AcknowledgedResponse response = restHighLevelClient.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
        System.out.println("response.isAcknowledged() = " + response.isAcknowledged());
    }


}

八、使用java操作文档

1,增加文档

  • 增加文档需要 索引库名、文档id、文档内容(json格式)
/**
 * 增加文档
 */
@Test
public void addDocTest() throws IOException {
    // EsConstant.HOTEL_INDEX 索引库名
    IndexRequest indexRequest = new IndexRequest(EsConstant.HOTEL_INDEX);
    // 从数据库获取文档
    Hotel hotel = hotelService.getById(36934L);
    HotelDoc hotelDoc = new HotelDoc(hotel);
    String jsonHotel = JSON.toJSONString(hotelDoc);
    // 设置文档id
    indexRequest.id(hotel.getId().toString());
    // 设置文档数据
    indexRequest.source(jsonHotel, XContentType.JSON);
    IndexResponse response = restHighLevelClient
            .index(indexRequest, RequestOptions.DEFAULT);
}

2,查询文档

  • 查询文档需要 索引库名、文档id
/**
 * 查询文档
 */
@Test
public void getDocTest() throws IOException {
    // id是字符串形式,所以不用带L
    GetRequest getRequest = new GetRequest(EsConstant.HOTEL_INDEX, "36934");
    // response 中"_source"包含对象数据
    GetResponse response = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
    
    String source = response.getSourceAsString();
    HotelDoc hotelDoc = JSON.parseObject(source, HotelDoc.class);
    System.out.println("hotelDoc = " + hotelDoc);
}

3,修改文档

  • 修改文档需要 索引库名、文档id、修改的内容
/**
 * 修改文档1
 */
@Test
public void updateDocTest() throws IOException {
    UpdateRequest updateRequest = new UpdateRequest(EsConstant.HOTEL_INDEX, "36934");
    // 修改文档 - 局部修改
    updateRequest.doc(
            XContentType.JSON, 
        	// 依次代表 key、value,
        	// 表示address的值改为"新的,第三次","city"的值改为 "新的城市!第二次"
            "address", "新的,第三次", 
            "city", "新的城市!第二次"
    );
    UpdateResponse response = restHighLevelClient
            .update(updateRequest, RequestOptions.DEFAULT);
}



/**
 * 修改文档2
 */
@Test
public void updateDocTest() throws IOException {
    UpdateRequest updateRequest = new UpdateRequest(EsConstant.HOTEL_INDEX, "36934");
    
    // 修改文档 - 全局修改
	Hotel hotel = hotelService.getById(36934L);
	hotel.setAddress("新的!");
	hotel.setCity("新的城市!");
	String source = JSON.toJSONString(hotel);
	updateRequest.doc(source, XContentType.JSON);

    UpdateResponse response = restHighLevelClient
            .update(updateRequest, RequestOptions.DEFAULT);
}



/**
 * 修改文档3
 */
@Test
public void updateDocTest() throws IOException {
    UpdateRequest updateRequest = new UpdateRequest(EsConstant.HOTEL_INDEX, "36934");
   
    // 修改文档 - 局部修改
	HashMap<String, Object> map = new HashMap<>();
	map.put("address", "新的,第二次");
	updateRequest.doc(map);
    
    UpdateResponse response = restHighLevelClient
            .update(updateRequest, RequestOptions.DEFAULT);
}

4,删除文档

  • 删除文档需要 索引库名、文档id
/**
 * 删除文档
 */
@Test
public void deleteDocTest() throws IOException {
    DeleteRequest deleteRequest = new DeleteRequest(EsConstant.HOTEL_INDEX, "36934");
    restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
}

5,完整代码,包含批量操作

package cn.itcast.hotel;

import cn.itcast.hotel.constant.EsConstant;
import cn.itcast.hotel.pojo.Hotel;
import cn.itcast.hotel.pojo.HotelDoc;
import cn.itcast.hotel.service.IHotelService;
import com.alibaba.fastjson.JSON;
import org.elasticsearch.action.bulk.BulkRequest;
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.action.index.IndexResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
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.HashMap;
import java.util.List;

/**
 * @author 星辰鱼
 * @version 1.0
 * @date 2023/5/19 16:44
 */
@SpringBootTest
@SuppressWarnings("all")
public class TestDoc {

    @Autowired
    public RestHighLevelClient restHighLevelClient;
    @Autowired
    public IHotelService hotelService;


    /**
     * 批量修改
     */
    @Test
    public void updateBulkTest() throws IOException {

        BulkRequest bulkRequest = new BulkRequest();

        // 获取数据库数据
        List<Hotel> hotelList = hotelService.list();

        hotelList.stream().forEach(hotel -> {
            UpdateRequest updateRequest = new UpdateRequest(EsConstant.HOTEL_INDEX, hotel.getId().toString());

            HashMap<String, Object> map = new HashMap<>();
            map.put("address", "新的地址,第二");
            UpdateRequest request = updateRequest.doc(map);
            bulkRequest.add(request);
        });

        restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);

    }


    /**
     * 批量删除
     */
    @Test
    public void getBulkTest() throws IOException {

        BulkRequest bulkRequest = new BulkRequest();

        //获取数据库所有数据
        List<Hotel> hotelList = hotelService.list();
        hotelList.stream().forEach(hotel -> {
            bulkRequest.add(new DeleteRequest(
                    EsConstant.HOTEL_INDEX)
                    .id(hotel.getId().toString()));
        });

        restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
    }


    /**
     * 批量插入
     */
    @Test
    public void bulkDocTest() throws IOException {

        BulkRequest bulkRequest = new BulkRequest();

        // 获取数据库所以数据
        List<Hotel> hotelList = hotelService.list();
        hotelList.stream().forEach(hotel -> {
            HotelDoc hotelDoc = new HotelDoc(hotel);
            // 将hotelDoc转为json格式
            String source = JSON.toJSONString(hotelDoc);

            bulkRequest.add(
                    new IndexRequest(EsConstant.HOTEL_INDEX)
                            .id(hotel.getId().toString())
                            .source(source, XContentType.JSON)
            );

        });

        restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);


    }


    /**
     * 删除文档
     */
    @Test
    public void deleteDocTest() throws IOException {
        DeleteRequest deleteRequest = new DeleteRequest(EsConstant.HOTEL_INDEX, "36934");
        restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
    }


    /**
     * 修改文档
     */
    @Test
    public void updateDocTest() throws IOException {
        UpdateRequest updateRequest = new UpdateRequest(EsConstant.HOTEL_INDEX, "36934");

        /**
         *         修改文档 - 全局修改
         *         Hotel hotel = hotelService.getById(36934L);
         *         hotel.setAddress("新的!");
         *         hotel.setCity("新的城市!");
         *         String source = JSON.toJSONString(hotel);
         *
         *         updateRequest.doc(source, XContentType.JSON);
         */

        /**
         *         修改文档 - 局部修改1
         *         HashMap<String, Object> map = new HashMap<>();
         *         map.put("address", "新的,第二次");
         *         updateRequest.doc(map);
         */
        // 修改文档 - 局部修改2
        updateRequest.doc(XContentType.JSON, "address", "新的,第三次", "city", "新的城市!第二次");

        UpdateResponse response = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
    }


    /**
     * 查询文档
     */
    @Test
    public void getDocTest() throws IOException {
        // id是字符串形式,所以不用带L
        GetRequest getRequest = new GetRequest(EsConstant.HOTEL_INDEX, "36934");
        // response 中"_source"包含对象数据
        GetResponse response = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
        String source = response.getSourceAsString();
        HotelDoc hotelDoc = JSON.parseObject(source, HotelDoc.class);
        System.out.println("hotelDoc = " + hotelDoc);
    }



    /**
     * 增加文档
     */
    @Test
    public void addDocTest() throws IOException {
        IndexRequest indexRequest = new IndexRequest(EsConstant.HOTEL_INDEX);
        // 从数据库获取文档
        Hotel hotel = hotelService.getById(36934L);

        HotelDoc hotelDoc = new HotelDoc(hotel);
        String jsonHotel = JSON.toJSONString(hotelDoc);

        // 设置文档id
        indexRequest.id(hotel.getId().toString());
        // 设置文档数据
        indexRequest.source(jsonHotel, XContentType.JSON);
        IndexResponse response = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值