【数据篇】SpringBoot 整合 Elasticsearch 实践数据搜索引擎

【数据篇】SpringBoot 整合 Elasticsearch 实践数据搜索引擎,第1张

写在最前
  • Elasticsearch 入门必读
  • Docker安装ELK
  • Spring Data Elasticsearch 参考文档
版本选择
Spring Data Release TrainSpring Data ElasticsearchElasticsearchSpring FrameworkSpring Boot
2021.1 (Q)4.3.x7.15.25.3.x2.5.x
2021.0 (Pascal)4.2.x7.12.05.3.x2.5.x
2020.0 (Ockham)4.1.x7.9.35.3.22.4.x
Neumann4.0.x7.6.25.2.122.3.x
Moore3.2.x6.8.125.2.122.2.x
Lovelace3.1.x6.2.25.1.192.1.x
Kay3.0.x5.5.05.0.132.0.x
Ingalls2.1.x2.4.04.3.251.5.x
SpringBoot 整合 Elasticsearch

Demo 使用 Spring Boot 使用 2.6.6 版本,默认对应 Elasticsearch 7.15.2(环境安装的 7.17.2)。Deom 地址:mingyue-springboot-elasticsearch

1.添加依赖
<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-data-elasticsearchartifactId>
dependency>
2.修改配置文件
elastic:
  address: http://ip:9200
3.添加 Elasticsearch 配置类
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;

/**
 * Elasticsearch 配置类
 *
 * @author Strive
 */
@Slf4j
@Configuration
public class ElasticConfig extends AbstractElasticsearchConfiguration {
  @Value("${elastic.address}")
  private List<String> addressList;

  @Bean
  @Override
  public RestHighLevelClient elasticsearchClient() {
    HttpHost[] httpHosts = new HttpHost[addressList.size()];

    for (int i = 0; i < addressList.size(); i++) {
      String address = addressList.get(i);

      log.info("create elastic host:{}", address);
      httpHosts[i] = HttpHost.create(address);
    }
    return new RestHighLevelClient(RestClient.builder(httpHosts));
  }
}
4.测试连接
import java.io.IOException;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;

/**
 * @author Strive
 * @date 2022/4/20 10:35
 * @description
 */
@SpringBootTest
public class ElasticsearchTest {

  @Autowired
  @Qualifier("elasticsearchClient")
  public RestHighLevelClient client;

  /** 创建索引测试 */
  @Test
  public void createIndexTest() throws IOException {
    CreateIndexRequest request = new CreateIndexRequest("mingyue");
    CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);

    // 查看是否创建成功
    System.out.println(response.isAcknowledged());
    client.close();
  }
}

执行日志如下:

true

访问:http://ip:5601/app/management/data/index_management/indices

mingyue 索引存在即可!

常用注解 @Document

标示映射到 Elasticsearch 文档上的领域对象。

public @interface Document {
  	//索引库名次,mysql中数据库的概念
	String indexName();
  	//文档类型,mysql中表的概念
	String type() default "";
  	//默认分片数
	short shards() default 5;
  	// 默认副本数量
	short replicas() default 1;
}
@Id

表示是文档的 id,文档可以认为是 mysql 中表行的概念。

@Field

文档中字段说明。

public @interface Field {
  	// 文档中字段的类型
	FieldType type() default FieldType.Auto;
  	// 是否建立倒排索引
	boolean index() default true;
  	// 是否进行存储
	boolean store() default false;
  	// 分词器名次
	String analyzer() default "";
}
// 为文档自动指定元数据类型
public enum FieldType {
    // 会进行分词并建了索引的字符类型
	Text,
	Integer,
	Long,
	Date,
	Float,
	Double,
	Boolean,
	Object,
    // 自动判断字段类型
	Auto,
    // 嵌套对象类型
	Nested,
	Ip,
	Attachment,
    // 不会进行分词建立索引的类型
	Keyword
}
实践数据搜索

古诗词检索,Demo 地址:mingyue-springboot-elasticsearch

1.定义 AncientPoetry 实体

analyzer = “ik_max_word” 需要 elasticsearch 安装 IK 分词器

import java.io.Serializable;
import java.util.Date;
import lombok.Data;
import lombok.ToString;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.DateFormat;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;

/**
 * 古诗词
 *
 * @author Strive
 */
@Data
@ToString
@Document(indexName = "ancient_poetry")
public class AncientPoetry implements Serializable {

  @Id
  @Field(type = FieldType.Text)
  private String id;

  @Field(type = FieldType.Text, analyzer = "ik_max_word")
  private String title;

  @Field(type = FieldType.Text, analyzer = "ik_max_word")
  private String author;

  @Field(type = FieldType.Text, analyzer = "ik_max_word")
  private String content;

  @Field(type = FieldType.Date, format = DateFormat.basic_date_time)
  private Date createTime;
}
2.创建接口 ESAncientPoetryRepository

该接口继承了 ElasticsearchRepository 接口,ElasticsearchRepository 接口定义了 Elasticsearch 的 CRUD,继承了该接口的接口甚至无需定义任何其他的方法就能满足基本需求。最牛的是通过定义的方法名就能自动创建各种查询!!!

import com.csp.mingyue.es.model.AncientPoetry;
import java.util.List;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

/**
 * 古诗词 ES 该接口继承了ElasticsearchRepository接口,ElasticsearchRepository接口定义了Elasticsearch的CRUD,
 * 继承了该接口的接口甚至无需定义任何其他的方法就能满足基本需求。
 *
 * @author Strive
 * @date 2022/4/26 09:46
 * @description
 */
public interface EsAncientPoetryRepository extends ElasticsearchRepository<AncientPoetry, String> {
  /**
   * 关键字检索 标题 或 内容
   *
   * @param title 标题
   * @param content 内容
   * @return 古诗词列表
   */
  List<AncientPoetry> findByTitleOrContent(String title, String content);
}
3.编写 Service
import com.csp.mingyue.es.model.AncientPoetry;
import com.csp.mingyue.es.repository.EsAncientPoetryRepository;
import java.util.List;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * ESAncientPoetry service 层
 *
 * @author Strive
 * @date 2022/4/26 10:07
 */
@Service
@RequiredArgsConstructor
public class EsAncientPoetryService {

  private final EsAncientPoetryRepository esAncientPoetryRepository;

  /**
   * 添加古诗词到ES
   *
   * @param ancientPoetry 古诗词
   */
  public boolean addAncientPoetry(AncientPoetry ancientPoetry) {
    esAncientPoetryRepository.save(ancientPoetry);
    return Boolean.TRUE;
  }

  /**
   * 根据ID查询古诗词
   *
   * @param id 古诗词ID
   */
  public AncientPoetry getById(String id) {
    Optional<AncientPoetry> ancientPoetryOptional = esAncientPoetryRepository.findById(id);

    return ancientPoetryOptional.orElse(null);
  }

  /**
   * 关键字检索 标题 或 内容
   *
   * @param keyword 关键字
   */
  public List<AncientPoetry> findAncientPoetry(String keyword) {
    return esAncientPoetryRepository.findByTitleOrContent(keyword, keyword);
  }
}
4.编写接口
import com.csp.mingyue.es.model.AncientPoetry;
import com.csp.mingyue.es.service.EsAncientPoetryService;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * ES  *** 作接口
 *
 * @author Strive
 * @date 2022/4/26 09:52
 * @description
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/es/ancientPoetry")
public class EsAncientPoetryController {

  private final EsAncientPoetryService esAncientPoetryService;

  @PostMapping
  public ResponseEntity<Boolean> add(@RequestBody AncientPoetry ancientPoetry) {
    return ResponseEntity.ok(esAncientPoetryService.addAncientPoetry(ancientPoetry));
  }

  @GetMapping("{id}")
  public ResponseEntity<AncientPoetry> get(@PathVariable String id) {
    return ResponseEntity.ok(esAncientPoetryService.getById(id));
  }

  @GetMapping("/search")
  public ResponseEntity<List<AncientPoetry>> findAncientPoetry(String keyword) {
    return ResponseEntity.ok(esAncientPoetryService.findAncientPoetry(keyword));
  }
}
5.测试

启动项目后,查看 kibana 是否有 ancient_poetry 索引

添加古诗词

POST http://127.0.0.1:8080/es/ancientPoetry

Body 类型 : application/json

{
    "id": "1",
    "title": "水调歌头",
    "author": "苏轼",
    "content": "明月几时有,把酒问青天。不知天上宫阙,今夕是何年。我欲乘风归去,又恐琼楼玉宇,高处不胜寒。起舞弄清影,何似在人间。",
    "createTime": "2022-04-26"
}
根据用户ID获取古诗词

GET http://127.0.0.1:8080/es/ancientPoetry/1

检索古诗词

GET http://127.0.0.1:8080/es/ancientPoetry/search?keyword=明月

[
    {
        "id": "2",
        "title": "西江月·夜行黄沙道中",
        "author": "辛弃疾",
        "content": "明月别枝惊鹊,清风半夜鸣蝉。稻花香里说丰年,听取蛙声一片。",
        "createTime": "2022-04-26T00:00:00.000+00:00"
    },
    {
        "id": "1",
        "title": "水调歌头",
        "author": "苏轼",
        "content": "明月几时有,把酒问青天。不知天上宫阙,今夕是何年。我欲乘风归去,又恐琼楼玉宇,高处不胜寒。起舞弄清影,何似在人间。",
        "createTime": "2022-04-26T00:00:00.000+00:00"
    }
]

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/741168.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-04-28
下一篇2022-04-28

发表评论

登录后才能评论

评论列表(0条)

    保存