当前位置:   article > 正文

ElasticSearch系列 - SpringBoot整合ES:实现文档的增删改操作_springboot 整合es 创建文档

springboot 整合es 创建文档


https://www.elastic.co/guide/en/elasticsearch/reference/current/search-your-data.html
https://www.elastic.co/guide/cn/elasticsearch/guide/current/_retrieving_a_document.html

1. ElasticSearch和kibana的安装和配置

① 下载地址:https://www.elastic.co/cn/downloads/past-releases/elasticsearch-7-4-2

② 修改elasticsearch.yml文件:

 cluster.name: my-application
 path.data: D:/install/elasticsearch-7.4.2-windows-x86_64/elasticsearch-7.4.2/data
 path.logs: D:/install/elasticsearch-7.4.2-windows-x86_64/elasticsearch-7.4.2/logs
  • 1
  • 2
  • 3

③ 配置环境变量:D:\install\elasticsearch-7.4.2-windows-x86_64\elasticsearch-7.4.2\bin

④ 下载ik分词器:https://github.com/medcl/elasticsearch-analysis-ik/releases?after=v7.4.2

⑤ 解压ik分词器,必须解压到D:\install\elasticsearch-7.4.2-windows-x86_64\elasticsearch-7.4.2\plugins\ik目录下

⑥ 点击elasticsearch.bat启动elasticsearch服务,并访问:localhsot:9200

kibana下载地址:https://www.elastic.co/cn/downloads/past-releases/kibana-7-4-2

⑧ 修改kibana.yml文件(不必须):

 server.port: 5601
 server.host: "localhost"
 elasticsearch.hosts: ["http://localhost:9200"]
 i18n.locale: "zh-CN"
  • 1
  • 2
  • 3
  • 4

⑨ 点击kibana.bat启动kibana服务(一定要先启动es):

⑦ kibana下载地址:https://www.elastic.co/cn/downloads/past-releases/kibana-7-4-2

⑧ 修改kibana.yml文件(不必须):

 server.port: 5601
 server.host: "localhost"
 elasticsearch.hosts: ["http://localhost:9200"]
 i18n.locale: "zh-CN"
  • 1
  • 2
  • 3
  • 4

⑨ 点击kibana.bat启动kibana服务(一定要先启动es)

⑩ 访问localhost:5601

2. SpringBoot 项目环境搭建

1、创建项目:ElasticSearch和SpringBoot的版本一定要对应,否则会报各种错误

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <!-- 这里我的springboot的版本使用是2.3.2 -->
        <version>2.3.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.xiao</groupId>
    <artifactId>estest</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>estest</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <!-- 这里必须要填写,因为springboot2.3.2默认的elasticsearch版本为7.6.2,我们使用的是7.4.2,不更改会产生版本不兼容等问题 -->
        <elasticsearch.version>7.4.2</elasticsearch.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- 这里我使用的是elasticsearch的high-level-client 版本要和你的elasticsearch版本对应-->
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.4.2</version>
        </dependency>

        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-core</artifactId>
            <version>5.6.5</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.10</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.76</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85

2、创建一个配置类,用于配置Elasticsearch的集群信息:

@Configuration
public class ElasticSearchConfig {
    @Bean
    public RestHighLevelClient restHighLevelClient(){
        RestClientBuilder builder = RestClient.builder(new HttpHost("localhost",9200,"http"));
        RestHighLevelClient client = new RestHighLevelClient(builder);
        return client;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

3. 创建索引

1、在项目的resource/elasticsearch目录下创建一个文件mapping.json文件定义索引的映射:

{
  "properties": {
    "categoryId": {
      "type": "keyword"
    },
    "content": {
      "type": "text",
      "analyzer": "ik_max_word",
      "search_analyzer": "ik_smart"
    },
    "name": {
      "analyzer": "ik_max_word",
      "search_analyzer": "ik_smart",
      "type": "text"
    },
    "creator": {
      "type": "keyword"
    },
    "editor": {
      "type": "keyword"
    },
    "from": {
      "type": "keyword"
    },
    "id": {
      "type": "keyword"
    },
    "tags": {
      "type": "keyword"
    },
    "updateTime": {
      "type": "date",
      "format": "yyyy-MM-dd HH:mm:ss||epoch_millis"
    },
    "createTime": {
      "type": "date",
      "format": "yyyy-MM-dd HH:mm:ss||epoch_millis"
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

2、项目启动的时候判断knowledge索引是否存在并根据定义的映射创建该索引:

@Slf4j
@Service
public class ElasticSearchImpl {

    private static final String KNOWLEDGE_INDEX = "knowledge";

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @PostConstruct
    public void init(){
        try {
            // 查询索引
            GetIndexRequest request = new GetIndexRequest(KNOWLEDGE_INDEX);
            boolean exist = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
            if (!exist) {
                CreateIndexRequest createIndexRequest = new CreateIndexRequest("knowledge");
                ClassPathResource mappingResource = new ClassPathResource("elasticsearch/mapping.json");
                byte[] bytes = FileCopyUtils.copyToByteArray(mappingResource.getInputStream());
                String json = new String(bytes, StandardCharsets.UTF_8);
                createIndexRequest.mapping(json, XContentType.JSON);
                restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
            }
        } catch (IOException e) {
            log.error("failed to create index mapping:", e);
            throw new CommonException("elasticsearch.create.index.failed");
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

3、启动项目,在kibana客户端查看索引是否创建成功:

GET /knowledge/_search 
  • 1
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

说明索引添加成功。

4. 索引文档

1、定义一个映射对象:

@Data
public class Doc {
    private String id;
    private String name;
    private String content;
    private String creator;
    private String editor;
    private Date createTime;
    private Date updateTime;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

2、索引文档:

@Slf4j
@Service
public class ElasticSearchImpl {

    private static final String KNOWLEDGE_INDEX = "knowledge";

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    public void saveDoc(Doc doc) throws JsonProcessingException {
        IndexRequest indexRequest = new IndexRequest("knowledge");
        indexRequest.id(doc.getId());
        // ES使用 json 文档代表了一个对象
        String jsonString = new JsonMapper().writeValueAsString(doc);
        indexRequest.source(jsonString, XContentType.JSON);
        // ElasticSearch是近实时搜索,刚索引的文档并不是立即对搜索可见,需要手动刷新
        indexRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
        try {
            restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            log.error("failed to add document to elasticsearch,the doc is:{},the exception is {}", doc, e);
            throw new CommonException("elasticsearch.create.index.failed");
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

3、测试索引文档:

@SpringBootTest
@RunWith(SpringRunner.class)
public class BeanLoadServiceTest {

    @Autowired
    private ElasticSearchImpl elasticSearchImpl;

    @Test
    public void testSaveDoc(){
        // Elasticsearch 是面向文档的,意味着它存储整个对象或文档
        Doc doc = new Doc();
        doc.setId("1");
        doc.setName("茶花女");
        doc.setContent("这是一本非常好看的小说,有时间的小伙伴可以看一下");
        doc.setCreator("小仲马");
        doc.setEditor("小仲马");
        doc.setCreateTime(new Date());
        doc.setUpdateTime(new Date());
        elasticSearchImpl.saveDoc(doc);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

4、在kibana客户端查询索引中的文档:

GET /knowledge/_doc/1
  • 1
{
  "_index" : "knowledge",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "_seq_no" : 0,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "id" : "1",
    "name" : "茶花女",
    "content" : "这是一本非常好看的小说,有时间的小伙伴可以看一下",
    "creator" : "小仲马",
    "editor" : "小仲马",
    "createTime" : 1677229499680,
    "updateTime" : 1677229499680
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

5. 更新文档

1、更新文档:

@Slf4j
@Service
public class ElasticSearchImpl {

    private static final String KNOWLEDGE_INDEX = "knowledge";

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    public void updateDoc(Doc doc) throws JsonProcessingException {
        UpdateRequest updateRequest = new UpdateRequest(KNOWLEDGE_INDEX, doc.getId());
        String jsonString = new JsonMapper().writeValueAsString(doc);
        updateRequest.doc(jsonString, XContentType.JSON);
        updateRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
        try {
            restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            log.error("failed to update document to elasticsearch,the doc is:{},the exception is {}", doc, e);
            throw new CommonException("elasticsearch.create.index.failed");
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

2、测试更新文档:

@SpringBootTest
@RunWith(SpringRunner.class)
public class BeanLoadServiceTest {

    @Autowired
    private ElasticSearchImpl elasticSearchImpl;

    @Test
    public void testUpdateDoc() throws JsonProcessingException {
        // Elasticsearch 是面向文档的,意味着它存储整个对象或文档
        Doc doc = new Doc();
        doc.setId("1");
        doc.setName("茶花女");
        doc.setContent("这是一本非常好看的小说,有时间的小伙伴可以看一下");
        doc.setCreator("大仲马");
        doc.setEditor("大仲马");
        doc.setCreateTime(new Date());
        doc.setUpdateTime(new Date());
        elasticSearchImpl.saveDoc(doc);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

3、在kibana客户端查看索引中的文档:

{
  "_index" : "knowledge",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 2,
  "_seq_no" : 1,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "id" : "1",
    "name" : "茶花女",
    "content" : "这是一本非常好看的小说,有时间的小伙伴可以看一下",
    "creator" : "大仲马",
    "editor" : "大仲马",
    "createTime" : 1677229755142,
    "updateTime" : 1677229755142
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

6. 删除文档

1、删除文档:

@Slf4j
@Service
public class ElasticSearchImpl {

    private static final String KNOWLEDGE_INDEX = "knowledge";

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    public void deleteDoc(Set<String> ids) {
        DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest(KNOWLEDGE_INDEX);
        deleteByQueryRequest.setQuery(new TermsQueryBuilder("id", ids));
        deleteByQueryRequest.setRefresh(true);
        try {
            restHighLevelClient.deleteByQuery(deleteByQueryRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            log.error("failed to delete the document in elasticsearch,the doc ids is:{},the exception is {}", ids, e);
            throw new CommonException("elasticsearch.create.index.failed");
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

2、测试删除文档:

@SpringBootTest
@RunWith(SpringRunner.class)
public class BeanLoadServiceTest {

    @Autowired
    private ElasticSearchImpl elasticSearchImpl;

    @Test
    public void testDeleteDoc() throws JsonProcessingException {
        // Elasticsearch 是面向文档的,意味着它存储整个对象或文档
        List<String> list = Arrays.asList("1");
        elasticSearchImpl.deleteDoc(new HashSet<String>(list));
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

3、在kibana客户端查看删除的文档:

GET /knowledge/_doc/1
  • 1
{
  "_index" : "knowledge",
  "_type" : "_doc",
  "_id" : "1",
  "found" : false
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/67952
推荐阅读
相关标签
  

闽ICP备14008679号