ElasticSearch入门讲解+如何在SpringBoot中实现增删(一键删除所有)改查

目录

一、ElasticSearch入门介绍

1、整体架构预览

2、 ES简介

3、ES基本概念

4、ES的安装

5、Elasticsearch的使用场景详解

二、SpringBoot整合ES及ES的增删改查

1、SpringBoot整合ES

2、ES的增删改查

1)增 

2)删 

3)改

4)查

 三、建议阅读文档


一、ElasticSearch入门介绍

1、整体架构预览

                                          

2、 ES简介

详情参考官方文档中文版: https://es.xiaoleilu.com/010_Intro/50_Conclusion.html
1、简介
ES=elaticsearch简写, Elasticsearch是一个开源的高扩展的分布式全文检索引擎,它可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级别的数据。 
Elasticsearch也使用Java开发并使用Lucene作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单。


2. ES特点和优势
1)分布式实时文件存储,可将每一个字段存入索引,使其可以被检索到。 
2)实时分析的分布式搜索引擎。 
分布式:索引分拆成多个分片,每个分片可有零个或多个副本。集群中的每个数据节点都可承载一个或多个分片,并且协调和处理各种操作; 
负载再平衡和路由在大多数情况下自动完成。 
3)可以扩展到上百台服务器,处理PB级别的结构化或非结构化数据。也可以运行在单台PC上(已测试) 
4)支持插件机制,分词插件、同步插件、Hadoop插件、可视化插件等。


存在磁盘上,搜索的时候 通过内存,主要还是通过缓存的原理,所以 你给缓存足够大的内存 ,搜索的时候 基本上都是通过内存 搜索的,所以快

3、ES基本概念

1)索引(index)

 ES将数据存储于一个或多个索引中,索引是具有类似特性的文档的集合。类比传统的关系型数据库领域来说,索引相当于SQL中的一个数据库,或者一个数据存储方案(schema)。

索引由其名称(必须为全小写字符)进行标识,并通过引用此名称完成文档的创建、搜索、更新及删除操作。

一个ES集群中可以按需创建任意数目的索引。

2)类型(Type) 

 类型是索引内部的逻辑分区(category/partition),然而其意义完全取决于用户需求。因此,一个索引内部可定义一个或多个类型(type)。一般来说,类型就是为那些拥有相同的域的文档做的预定义。

例如,在索引中,可以定义一个用于存储用户数据的类型,一个存储日志数据的类型,以及一个存储评论数据的类型。类比传统的关系型数据库领域来说,类型相当于“表”。

 3)文档(Document)

文档是Lucene索引和搜索的原子单位,它是包含了一个或多个域的容器,基于JSON格式进行表示。文档由一个或多个域组成,每个域拥有一个名字及一个或多个值,有多个值的域通常称为“多值域”。每个文档可以存储不同的域集,但同一类型下的文档至应该有某种程度上的相似之处。

相当于mysql表中的一行

4)映射(Mapping)

  ES中,所有的文档在存储之前都要首先进行分析。用户可根据需要定义如何将文本分割成token、哪些token应该被过滤掉,以及哪些文本需要进行额外处理等等。另外,ES还提供了额外功能,例如将域中的内容按需排序。事实上,ES也能自动根据其值确定域的类型。

5)节点(Node)

 运行了单个实例的ES主机称为节点,它是集群的一个成员,可以存储数据、参与集群索引及搜索操作。类似于集群,节点靠其名称进行标识,默认为启动时自动生成的随机Marvel字符名称。用户可以按需要自定义任何希望使用的名称,但出于管理的目的,此名称应该尽可能有较好的识别性。节点通过为其配置的ES集群名称确定其所要加入的集群。

 6)集群(cluster)

ES可以作为一个独立的单个搜索服务器。不过,为了处理大型数据集,实现容错和高可用性,ES可以运行在许多互相合作的服务器上。这些服务器的集合称为集群。

7) 分片(Shard)

  ES的“分片(shard)”机制可将一个索引内部的数据分布地存储于多个节点,它通过将一个索引切分为多个底层物理的Lucene索引完成索引数据的分割存储功能,这每一个物理的Lucene索引称为一个分片(shard)。

当有大量的文档时,由于内存的限制、磁盘处理能力不足、无法足够快的响应客户端的请求等,一个节点可能不够。这种情况下,数据可以分为较小的分片。每个分片放到不同的服务器上。 
当你查询的索引分布在多个分片上时,ES会把查询发送给每个相关的分片,并将结果组合在一起,而应用程序并不知道分片的存在。即:这个过程对用户来说是透明的。 


   Shard有两种类型:primary和replica,即主shard及副本shard。Primary shard用于文档存储,每个新的索引会自动创建5个Primary shard,当然此数量可在索引创建之前通过配置自行定义,不过,一旦创建完成,其Primary shard的数量将不可更改。Replica shard是Primary Shard的副本,用于冗余数据及提高搜索性能。每个Primary shard默认配置了一个Replica shard,但也可以配置多个,且其数量可动态更改。ES会根据需要自动增加或减少这些Replica shard的数量。

   ES集群可由多个节点组成,各Shard分布式地存储于这些节点上。

ES可自动在节点间按需要移动shard,例如增加节点或节点故障时。简而言之,分片实现了集群的分布式存储,而副本实现了其分布式处理及冗余功能。

8)副本(Replica)

 为提高查询吞吐量或实现高可用性,可以使用分片副本。 
副本是一个分片的精确复制,每个分片可以有零个或多个副本。ES中可以有许多相同的分片,其中之一被选择更改索引操作,这种特殊的分片称为主分片。 


当主分片丢失时,如:该分片所在的数据不可用时,集群将副本提升为新的主分片。

 9)ELK

ELK=elasticsearch+Logstash+kibana 
elasticsearch:后台分布式存储以及全文检索 
logstash: 日志加工、“搬运工” 
kibana:数据可视化展示。、
 
ELK架构为数据分布式存储、可视化查询和日志解析创建了一个功能强大的管理链。 三者相互配合,取长补短,共同完成分布式大数据处理工作

10)数据结构  与mysql对比

                           

4、ES的安装

请下载文档:在Linux系统安装elasticsearch步骤+ElasticSearch基础讲解.docx

5、Elasticsearch的使用场景详解

1、场景—:使用Elasticsearch作为主要的后端

2、场景二:在现有系统中增加elasticsearch

3、场景三:使用elasticsearch和现有的工具

 详细情况,请阅读博文:https://blog.csdn.net/laoyang360/article/details/52227541

二、SpringBoot整合ES及ES的增删改查

1、SpringBoot整合ES

1)创建SpringBoot项目,导入jar包

   <!--ES包-->
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>transport</artifactId>
            <version>5.5.3</version>
            <exclusions>
                <exclusion>
                    <groupId>*</groupId>
                    <artifactId>transport-netty4-client</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.plugin</groupId>
            <artifactId>transport-netty4-client</artifactId>
            <version>5.5.3</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>5.5.3</version>
        </dependency>

        <dependency>
            <groupId>org.elasticsearch.plugin</groupId>
            <artifactId>delete-by-query</artifactId>
            <version>2.4.1</version>
        </dependency>
   <!-- es需要用到log4j 2.7以下版本 -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.6.2</version>
        </dependency> 

 

2)config配置文件

package xmcc.mll_es_8083.config;


import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;

@Configuration
public class ElasticsearchConfig {
    @Bean
    public TransportClient client() throws UnknownHostException{
        //注意这儿是tcp链接 是9300
        TransportAddress transportAddress = new InetSocketTransportAddress(InetAddress.getByName("192.168.1.170"), 9300);
        //集群配置     设置集群名称
//        Settings settings = Settings.builder().put("cluster.name", "xmcc").build();
//        TransportClient preBuiltTransportClient = new PreBuiltTransportClient(settings);
        //单机配置
        TransportClient preBuiltTransportClient = new PreBuiltTransportClient(Settings.EMPTY);
        preBuiltTransportClient.addTransportAddress(transportAddress);
        return preBuiltTransportClient;
    }
}

 

2、ES的增删改查

写在前面:存储数据的实体类EsProduct如下;

package xmcc.mll_es_8083.entity;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

import java.util.Date;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class EsProduct implements Serializable {

    private long productId;
    private String title;
    private String sell_point;
    private double price;
    private Date create_time;
    private String category;
    private String brand;

}

复杂查询的实体类如下:

package xmcc.mll_es_8083.dto;

import io.swagger.annotations.ApiModel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@ApiModel("查询 Dto")
public class QueryProductDto {
    //输入框输入
    private String keyWord;
    //选购热点
    private String sell_point;
    //价格区间:格式:100-200
    private String price;
    //是否根据上架时间排序 新上架在前
    private boolean create_timeBoolean;
    //分类
    private String category;
    //品牌
    private String brand;

    //当前页码,从0页开始
    private int page;
}

 

1)增 

根据需要存储的数据创建对应的实体类EsProduct

  public ResultResponse addProduct(EsProduct esProduct) throws IOException, ParseException {
        log.info("添加的数据为:{}", esProduct);
        //参数1:输入索引=mysql的dataBase   参数2:type名称=mysql中的表名
        IndexResponse indexResponse = transportClient.prepareIndex("mll", "product").
                //指定json字符串
                        setSource(JsonUtil.object2string(esProduct), XContentType.JSON).get();
        //返回查看数据是否成功
        return ResultResponse.success(indexResponse);
    }

2)删 

根据条件删除部分数据

    //根据某个条件删除文档数据
    public ResultResponse deleteProduct(long productId ){
        //根据productId删除对应数据
        DeleteByQueryRequestBuilder builder = DeleteByQueryAction.INSTANCE
                .newRequestBuilder(transportClient)
                .filter(QueryBuilders.termQuery("productId", productId)).source("mll");
        BulkByScrollResponse response = builder.get();
        long deleted = response.getDeleted();
        log.info("删除的条数为:{}",deleted);
        return ResultResponse.success();
    }

一键删除所有数据

//一键删除所有   删除条件不设置即可
 DeleteByQueryRequestBuilder builder = DeleteByQueryAction.INSTANCE
                .newRequestBuilder(transportClient)
                .filter(QueryBuilders.boolQuery()).
                        source("mll");
        BulkByScrollResponse response = builder.get();
        long deleted = response.getDeleted();
        log.info("删除的条数为:{}", deleted);

3)改

 public ResultResponse updateProduct(EsProduct esProduct) throws IOException, ParseException {
        log.info("修改的数据为:{}", esProduct);
        //输入索引 与type名称   这儿的es  id就直接写死了
        // TODO:业务逻辑肯定是先查询到ES自动生成的id然后再修改
        UpdateResponse updateResponse = transportClient.prepareUpdate("mll", "product", "AWsdQhh8klBAmP0UjTSR").
                //指定json字符串
                        setDoc(JsonUtil.object2string(esProduct), XContentType.JSON).get();
        if (updateResponse.status() == RestStatus.OK) {
            return ResultResponse.success();
        }
        return ResultResponse.fail();
    }

4)查

该处直接展示复杂查询,即根据可输入查询条件创建对应的实体类QueryProductDto,判断实体类属性是否为null,设置对应的过滤条件


public ResultResponse query(QueryProductDto productDto) {
        log.info("查询的数据为:{}", productDto);
        //通过基本的bool查询
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //创建查询对象  setTypes可以加入多个类型
         SearchRequestBuilder searchRequestBuilder = transportClient.
                prepareSearch("mll").setTypes("product");

        //先对查询数据进行判断  如果不为空 就添加查询数据  前面是字段名
        //输入框输入
        if (productDto.getKeyWord()!= null) {
            log.warn("KeyWord查询:{}",productDto.getKeyWord());
            boolQueryBuilder.must(
                    //根据关键字查询 只要下面的字段中包含该数据,有的词语分词里面没有就查询不到,就需要前面学习的去自定义
                    // 就会被查询到 这儿使用title与sell_point
                    QueryBuilders.multiMatchQuery(
                            productDto.getKeyWord(),
                            "title", "sell_point"
                    )
            );
        }
            //选购热点
        if (productDto.getSell_point()!=null){
            log.warn("Sell_point查询:{}",productDto.getSell_point());
            boolQueryBuilder.filter(QueryBuilders.termQuery(
                    "sell_point", productDto.getSell_point()));
        }

            //分类
      if (productDto.getCategory()!=null){
            log.warn("Category查询:{}",productDto.getCategory());

            boolQueryBuilder.filter(QueryBuilders.termQuery
                    ("category", productDto.getCategory()));

        }
            //品牌
         if (productDto.getBrand()!=null){
            log.warn("Brand查询:{}",productDto.getBrand());
            boolQueryBuilder.filter(QueryBuilders.termQuery
                    ("brand", productDto.getBrand()));
        }

        //根据上架时间排序 新上架在前
        if (productDto.isCreate_timeBoolean()){
            log.warn("Create_timeBoolean查询:{}",productDto.isCreate_timeBoolean());
            searchRequestBuilder.addSort("create_time",SortOrder.DESC );
        }
        //价格区间:格式:100-200
        if (productDto.getPrice()!=null){
            String price = productDto.getPrice();
            log.warn("price查询:{}",price);

            String[] strings = price.split("-");
            searchRequestBuilder.setPostFilter(QueryBuilders.rangeQuery
                    ("price").from(strings[0]).to(strings[1]));
        }

                //查询条件
        searchRequestBuilder.setQuery(boolQueryBuilder)
                //翻页 从第几条开始  查询多少条
                .setFrom(productDto.getPage())
                .setSize(3);

        log.info("查询到的数据为:{}", searchRequestBuilder.toString());
        //获得查询需要的数据结果
        SearchResponse searchResponse = searchRequestBuilder.get();
        //判断是否正常
        if (searchResponse.status() != RestStatus.OK) {
            log.warn("es查询数据异常,返回状态为:{}", searchResponse.status());
            return ResultResponse.fail();
        }
        //获得结果集
        SearchHits hits = searchResponse.getHits();
        List<EsProduct> products = new ArrayList<>();
        //遍历组装数据
        for (SearchHit hit : hits) {
            //字段名  这里先获得两个字段测试   如果以后字段多
            // 直接先把 es查询到的数据 转换为json字符串 然后再转成对象即可 ,这儿先详细的写一下
            //通过这个方法获得每条对象的json字符串 hit.getSourceAsString()
//            EsProduct esProduct1 = new EsProduct();
//            esProduct1.setBrand(String.valueOf(hit.getSource().get("brand")));
//            esProduct1.setPrice((double) hit.getSource().get("price"));

            EsProduct esProduct1 = JsonUtil.string2object(hit.getSourceAsString(), new TypeReference<EsProduct>() {
            });
            products.add(esProduct1);
        }
        return ResultResponse.success(products);
    }

 三、建议阅读文档

1、官方文档中文版: https://es.xiaoleilu.com/010_Intro/50_Conclusion.html

2、ES入门及其扩展:https://blog.csdn.net/makang110/article/details/80596017

3、Elasticsearch的使用场景深入详解:https://blog.csdn.net/laoyang360/article/details/52227541

 

 

  • 3
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以按照以下步骤使用 Spring Boot 和 Elasticsearch 实现增删改查的功能: 1. 添加依赖:在你的 Spring Boot 项目的 pom.xml 文件,添加 Elasticsearch 相关的依赖。例如: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> ``` 2. 配置 Elasticsearch:在你的 application.properties 或 application.yml 文件,配置 Elasticsearch 的连接信息。例如: ```yaml spring.data.elasticsearch.cluster-nodes=localhost:9200 ``` 3. 创建实体类:创建一个代表你要操作的数据的实体类,并使用注解来映射到 Elasticsearch 的索引和类型。例如: ```java import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; @Document(indexName = "your_index_name", type = "your_type_name") public class YourEntity { @Id private String id; private String name; // 其他属性和方法 } ``` 4. 创建数据访问接口:创建一个继承自 ElasticsearchRepository 的数据访问接口,该接口提供了一些基本的 CRUD 方法。例如: ```java import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; public interface YourEntityRepository extends ElasticsearchRepository<YourEntity, String> { // 可以根据需要添加自定义的查询方法 } ``` 5. 编写业务逻辑:在你的服务类使用 YourEntityRepository 来进行相关的数据操作。例如: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class YourService { @Autowired private YourEntityRepository repository; public YourEntity save(YourEntity entity) { return repository.save(entity); } public void delete(String id) { repository.deleteById(id); } public Iterable<YourEntity> findAll() { return repository.findAll(); } // 可以根据需要添加其他的查询方法和业务逻辑 } ``` 这样,你就可以通过调用 YourService 的方法来实现Elasticsearch增删改查操作了。希望对你有帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值