兜兜零元 发表于 2024-11-14 12:30:58

ES在SpringBoot集成利用

1. 在Docker中安装Elasticsearch

这里不了解docker甚至还没安装假造机的小伙伴可以去黑马的视频下找到资源,去下一个假造机

https://dis.qidao123.com/imgproxy/aHR0cHM6Ly9pbWctYmxvZy5jc2RuaW1nLmNuL2ltZ19jb252ZXJ0L2RjMGZkNjU1MjAyYzlhYjA0NTQxYWI1ZWZjNzUyYjY3LnBuZw==
这里就不对ES进行过多介绍了,具体的效果去b站看看叭,这里直接速成利用


[*]安装ES并启动
docker pull elasticsearch <ES版本>
eg:docker pull elasticsearch 7.7.0 docker run --name elasticsearch //启动容器并命名
-d -e ES_JAVA_OPTS="-Xms512m -Xmx512m" 设置初始堆和最大堆内存
-e "discovery.type=single-node" //配置ES以单节点模式运行,不集群
-p 9200:9200 //-p 用于端口映射,格式为<宿主机端口>:<容器端口>
-p 9300:9300 elasticsearch:7.7.0
也可以考虑用docker-compose一步到位进行安装
docker-compose 安装部署ElasticSearch 和 Kibana - 06 - 博客园 (cnblogs.com)
Kibana是ES的一个图形化操作工具,也可以利用es-head,这里我本人利用的是es-head,因此我讲的也是es-head安装
docker run后,浏览器访问ip:9200,假如显示以下内容即表示安装成功

https://dis.qidao123.com/imgproxy/aHR0cHM6Ly9pbWctYmxvZy5jc2RuaW1nLmNuL2ltZ19jb252ZXJ0LzRmYWIxOGEwNGI5NDI1ODVhOWZiODEwZmI1OWE0MDUyLnBuZw==
然后安装ES-head
#拉取镜像
docker pull mobz/elasticsearch-head:5

#创建容器
docker create --name elasticsearch-head -p 9100:9100 mobz/elasticsearch-head:5

#启动容器
docker start elasticsearch-head
or
docker start 容器id (docker ps -a 查看容器id )
//-a可以查看到未启动的容器 安装后启动,浏览器打开ip:9100

https://dis.qidao123.com/imgproxy/aHR0cHM6Ly9pbWctYmxvZy5jc2RuaW1nLmNuL2ltZ19jb252ZXJ0Lzc3MGQzMjM5YzExODVhMTIwMTEzYjNmZjU4ZTAzYmQ1LnBuZw==
这里直接输入ES地址是无法毗连的,需要进行跨域设置,因为是前后端分离的

[*]修改docker中elasticsearch的elasticsearch.yml文件
docker exec -it elasticsearch /bin/bash (进不去使用容器id进入)

vi config/elasticsearch.yml 在最下面参加两行
http.cors.enabled: true
http.cors.allow-origin: "*" 按i进入插入模式,就可以编辑了,编辑完按ESC退出编辑模式,输入:,进入底行模式,再输入wq强制保存并退出,这些下令不懂的话去学下liunx基础
好了之后退出并重启服务就可以运行了

https://dis.qidao123.com/imgproxy/aHR0cHM6Ly9pbWctYmxvZy5jc2RuaW1nLmNuL2ltZ19jb252ZXJ0L2I1MzYxM2ZmYzI4MDQ4N2NlNGNiYzNkM2RhZTI5ZTQyLnBuZw==
然后就可以了,至于分词器的话,根据业务需求来叭,也不是必须安装
Docker上安装部署Elasticsearch(ES)具体教程_docker安装es-CSDN博客想安装Kibana和ik的也可以看这篇文章
2. 在SpringBoot中利用ES

2.1. Spring Data Elasticsearch方式


[*]导入依靠
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
      </dependency>
[*]在设置文件中参加
server:
port: 8000 //可以改端口
spring:
elasticsearch:
    rest:
      uris:
      - http://localhost:9200 //es容器的地址,ip要换成虚拟机ip
[*]在java中编写实体对象,和ES进行映射
@Data //lombok的注解,要导入lombok
//定义索引,7以上的版本去掉了type属性
@Document(indexName = "goodsorder", shards = 1, replicas = 1)
@AllArgsConstructor
@NoArgsConstructor
public class OrderDoc implements Serializable {
   
   
    @Id
    @Field(type = FieldType.Keyword)
    private String id;

    @Field(type = FieldType.Long)
    private Long orderNo;

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

    //用来封装高亮的结果
    private Map<String, List<String>> highlights;

    public OrderDoc(String id, Long orderNo ,String title){
   
   
      this.id = id;
      this.orderNo = orderNo;
      this.title =title;
    }
}
[*]编写Repository接口
@Repository
//泛型是Doc对象和ID的类型
public interface OrderRepository extends ElasticsearchRepository<OrderDoc, String> {
   
   

}
[*]编写Service实现CRUD基本操作
public interface OrderDocService {
   
   

    void saveAll(List<OrderDoc> orderDocs);

    OrderDoc findById(String id);

    void deleteById(String id);

    void updateById(OrderDoc orderDoc);

    PageResponse<OrderDoc> findList(OrderDoc orderDoc, Integer pageIndex, Integer pageSize);

    PageResponse<OrderDoc> findAll(Integer pageIndex, Integer pageSize);

    PageResponse<OrderDoc> findHighlight(OrderDoc orderDoc, Integer pageIndex, Integer pageSize);
}
[*]实现类代码
@Service
public class OrderDocServiceImpl implements OrderDocService {
   
   

    @Autowired
    private OrderRepository orderRepository;
    @Autowired
    private ElasticsearchRestTemplate template;

    @Override
    public void saveAll(List<OrderDoc> orderDocs) {
   
   
      orderRepository.saveAll(orderDocs);
    }

    @Override
    public OrderDoc findById(String id) {
   
   
      return orderRepository.findById(id).orElse(null);
    }

    @Override
    public void deleteById(String id) {
   
   
      orderRepository.deleteById(id);
    }

    @Override
    public void updateById(OrderDoc orderDoc) {
   
   
      orderRepository.save(orderDoc);
    }

    @Override
    public PageResponse<OrderDoc> findList(OrderDoc orderDoc, Integer pageIndex, Integer pageSize) {
   
   
      CriteriaQuery criteriaQuery = new CriteriaQuery(
                new Criteria().and("title").contains(orderDoc.getTitle()),PageRequest.of(pageIndex,pageSize));

      SearchHits<OrderDoc> searchHits = template.search(criteriaQuery, OrderDoc.class);

      List<OrderDoc> orderDocList = searchHits.getSearchHits().stream()
                .map(orderDocSearchHit -> orderDocSearchHit.getContent()).collect(Collectors.toList());

      return new PageResponse<OrderDoc>(searchHits.getTotalHits() ,orderDocList);
    }

    @Override
    public PageResponse<OrderDoc> findAll(Integer pageIndex, Integer pageSize) {
   
   
      Page<OrderDoc> page = orderRepository.findAll(PageRequest.of(pageIndex, pageSize));
      return new PageResponse<OrderDoc>(page.getTotalElements(),page.getContent());
    }

    @Override
    public PageResponse<OrderDoc> findHighlight(OrderDoc orderDoc, Integer pageIndex, Integer pageSize) {
   
   
      //查询条件
      CriteriaQuery criteriaQuery = new CriteriaQuery(
                new Criteria().and("title").contains(orderDoc.getTitle()),
                PageRequest.of(pageIndex,pageSize));
      //高亮字段
      HighlightBuilder highlightBuilder = new HighlightBuilder();
      highlightBuilder.field("title").preTags("<font style='color:red'>").postTags("</font>");
      criteriaQuery.setHighlightQuery(new HighlightQuery(highlightBuilder));
      //搜索结果
      SearchHits<OrderDoc> searchHits = template.search(criteriaQuery, OrderDoc.class);

      List<OrderDoc> orderDocList = searchHits.get().map(searchHit -> {
   
   
            //把高亮结果添加到doc中中
            OrderDoc doc = searchHit.getContent();
            //获取高亮
            doc.setHighlights(searchHit.getHighlightFields());
            return doc;
      }).collect(Collectors.toList());

      //处理结果
      return new PageResponse<>(searchHits.getTotalHits() , orderDocList);
    }
}
[*]结果响应对象
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PageResponse<T> {
   
   
    private Long total;
    private List<T> list;
} 8.编写测试类进行测试
public class OrderDocServiceTest {
   
   

    @Autowired
    private OrderDocService orderDocService;

    @Test
    public void saveAll() {
   
   
      orderDocService.saveAll(Arrays.asList(
                new OrderDoc("1",100000l,"苹果电脑"),
                new OrderDoc("2",100000l,"苹果电脑"),
                new OrderDoc("3",100000l,"苹果电脑"),
                new OrderDoc("4",100000l,"苹果电脑"),
                new OrderDoc("5",100000l,"苹果电脑"),
                new OrderDoc("6",100000l,"苹果电脑"),
                new OrderDoc("7",100000l,"苹果电脑")
      ));
    }

    @Test
    public void findById() {
   
   
      System.out.println(orderDocService.findById("1"));
    }

    @Test
    public void deleteById() {
   
   
      orderDocService.deleteById("1");
    }

    @Test
    public void updateById() {
   
   
      OrderDoc orderDoc = orderDocService.findById("1");
      orderDoc.setTitle("华为电脑");
      orderDocService.updateById(orderDoc);
    }

    @Test
    public void findList() {
   
   
      OrderDoc orderDoc = new OrderDoc(null, 100l, "电脑");
      PageResponse<OrderDoc> response = orderDocService.findList(orderDoc, 0, 10);
      System.out.println(response.getTotal());
      response.getList().forEach(System.out::println);

    }

    @Test
    public void findAll() {
   
   
      PageResponse<OrderDoc> response = orderDocService.findAll( 0, 10);
      System.out.println(response.getTotal());
      response.getList().forEach(System.out::println);
    }

    @Test
    public void findHighlight() {
   
   
      OrderDoc orderDoc = new OrderDoc(null, 100l, "电脑",null);
      PageResponse<OrderDoc> response = orderDocService.findHighlight( orderDoc,0, 10);
      System.out.println(response.getTotal());
      response.getList().forEach(System.out::println);
    }
} 其中的高亮显示是在ES7.9.x版本才有的似乎,我在ES7.7版本显示报错,有一个方法不支持了。
因此我上网找了一篇支持高亮显示的文章进行参考,最终实现高亮显示的效果
elasticsearch与springboot整合之高亮显示处理方法_springboot 对接es7.17的高亮不通过注解-CSDN博客
总结:目前SpringBoot集成ES主要有两种方式

[*]通过Spring Data Elasticsearch,由SpringBoot官方集成好的直接利用即可,方便快捷,不过在一些高级查询上不太灵活
2.通过Java REST Client,可以针对行复杂操作或自定义行为的场景条件进行构造查询条件。
2.2. Java REST Client方式

利用步调:
1.导入依靠
<dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>elasticsearch-rest-high-level-client</artifactId>
        <version>7.10.1</version>
</dependency>
[*]在设置文件中设置毗连
elasticsearch:
host: 127.0.0.1
port: 9200
scheme: http
[*]编写设置类进行客户端毗连设置
@Configuration
public class ElasticsearchConfig {

        @Value("${elasticsearch.host}")
        private String host;

        @Value("${elasticsearch.port}")
        private int port;

        @Value("${elasticsearch.scheme}")
        private String scheme;

        @Bean
        public RestHighLevelClient restHighLevelClient() {
                RestClientBuilder builder = RestClient.builder(new HttpHost(host, port, scheme));
                return new RestHighLevelClient(builder);
        }
} 4.通过RestHighLevelClient提供的API来操作Elasticsearch数据。可以进行索引的创建、文档的增删改查等操作
注意:RestHighLevelClient在Elasticsearch 8.x版本后已被替换为Elasticsearch Java API Client,假如有需要的话就上网查下怎么用吧
页: [1]
查看完整版本: ES在SpringBoot集成利用