Elasticsearch入门及整合springboot

2023-05-16

1. Elasticsearch概述

1.1 搜索是什么

概念:用户输入想要的关键词,返回含有该关键词的所有信息。
场景:
	1. 互联网搜索:谷歌、百度、各种新闻首页
	2. 站内搜索(垂直搜索):企业OA查询订单、人员、部门,
	  					  电商网站内部搜索商品(淘宝、京东)场景。

1.2 数据库做搜索弊端

1.2.1 站内搜索(垂直搜索):
(若数据量小,简单搜索,可以使用数据库)

问题出现:

	1. 存储问题: 电商网站商品上亿条时,涉及到单表数据过大必须拆分表,
				数据库磁盘占用过大必须分库(mycat)。

	2. 性能问题:解决上面问题后,若查询“笔记本电脑”等关键词时,上亿条数据
				的商品名字段逐行扫描,性能跟不上。

	3. 不能分词搜索: 如搜索“笔记本电脑”,只能搜索完全和关键词一样的数据,
				那么数据量小时,搜索“笔记电脑”,“电脑”数据要不要给用户。
1.2.2互联网搜索:

肯定不会使用数据库搜索,数据量太大(PB级)

可以使用搜索引擎来解决数据库搜索的问题:
	搜索也是一款数据库,搜索可以进行分词搜索---搜索速度非常快

1.3 常见的搜索引擎

【solr】:  
	Solr是一个独立的企业级搜索应用服务器,
 	它对外提供类似于Web-service的API接口。
 	用户可以通过http请求,向搜索引擎服务器提交一定格式的XML文件,生成索引;
 	也可以通过Http Get操作提出查找请求,并得到XML格式的返回结果,
 	
 	特点:是一个高性能,采用Java开发,基于Lucene的全文搜索服务器.
 		同时对其进行了扩展,提供了比Lucene更为丰富的查询语言,
 		同时实现了可配置、可扩展并对查询性能进行了优化,
 		并且提供了一个完善的功能管理界面,是一款非常优秀的全文搜索引擎。

【ElasticSearch】:
	ElasticSearch是一个基于Lucene的搜索服务器。
	它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。
	Elasticsearch是用Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎。
	ElasticSearch用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。
	官方客户端在Java、.NET(C#)、PHP、Python、Apache Groovy、Ruby和许多其他语言中都是可用的。
	根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr,也是基于Lucene。

ElasticSearch与Solr比较:

  1. 当单纯的对已有数据进行搜索时,Solr更快
    在这里插入图片描述

  2. 当实时建立索引时,Solr会产生io阻塞,查询性能较差,ElasticSearch具有明显的优势
    在这里插入图片描述

  3. 随着数据量的增加,Solr的搜索效率会变得更低,而ElasticSearch却没有明显的变化
    在这里插入图片描述

     总结: 
     
     	1. es基本是开箱即用(解压就可以用!) ,非常简单。Solr 安装略微复杂一丢丢! 
     	2. Solr 利用Zookeeper进行分布式管理,而 Elasticsearch自身带有分布式协调管理功能. 
     	3. Solr 支持更多格式的数据,比如JSON、XML、CSV ,而 Elasticsearch仅支持json文件格式。 
     	4. Solr 官方提供的功能更多,而Elasticsearch本身更注重于核心功能,高级功能多有第三方插件提供,例如图形化界面需要kibana支撑 
     	5. Solr 查询快,但更新索引时慢(即插入删除慢) ,用于电商等查询多的应用; 
     	6. ES建立索引快(即查询慢) ,即实时性查询快,用于facebook新浪等搜索。 
     	7. Solr是传统搜索应用的有力解决方案,但Elasticsearch更适用于 新兴的实时搜索应用。 
     	8. Solr比较成熟,有一个更大,更成熟的用户、开发和贡献者社区, 而Elasticsearch相对开发维护者较少,更新太快,学习使用成本较高。
    

1.4 Elasticsearch介绍

The Elastic Stack, 包括 Elasticsearch【搜索,分析】、 Kibana【可视化】、 Beats 和 Logstash【数据的搜集】(也称为 ELK Stack)。

能够安全可靠地获取任何来源、任何格式的数据,然后实时地对数据进行搜索、分析和可视化。

Elaticsearch,简称为 ES, ES 是一个开源的高扩展的分布式全文搜索引擎, 是整个 ElasticStack 技术栈的核心。

它可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理 PB 级别的数据

它是搜索的一款数据库,支持的数据格式是json.

1.5 Elasticsearch的使用场景

国外:
	1. 维基百科,类似百度百科,“网络七层协议”的维基百科,全文检索,高亮,搜索推荐
	2. Stack Overflow(国外的程序讨论论坛),相当于程序员的贴吧。遇到it问题去上面发帖,热心网友下面回帖解答。
	3. GitHub(开源代码管理),搜索上千亿行代码。
	4. 电商网站,检索商品
	5. 日志数据分析,logstash采集日志,ES进行复杂的数据分析(ELK技术elasticsearch+logstash+kibana
	6. 商品价格监控网站,用户设定某商品的价格阈值,当低于该阈值的时候,
		发送通知消息给用户,比如说订阅《java编程思想》的监控,如果价格低于27块钱,就通知我,我就去买
	7. BI系统,商业智能(Business Intelligence)。大型连锁超市,分析全国网点传回的数据,
		分析各个商品在什么季节的销售量最好、利润最高。
		成本管理,店面租金、员工工资、负债等信息进行分析。从而部署下一个阶段的战略目标。

国内:
	1. 百度搜索,第一次查询,使用es。
	2.  OA、ERP系统站内搜索。

2. ES的安装

步骤:
(1)安装JDK,至少1.8.0_73以上版本,验证:java -version。

(2)下载和解压缩Elasticsearch安装包,查看目录结构。

	下载地址:https://www.elastic.co/cn/downloads/past-releases/
	这俩版本即可

在这里插入图片描述

在这里插入图片描述

目录结构
在这里插入图片描述
解压后,进入 bin 文件目录,点击 elasticsearch.bat 文件启动 ES 服务 。
注意: 9300 端口为 Elasticsearch 集群间组件的通信端口, 9200 端口为浏览器访问的 http协议 RESTful 端口。

打开浏览器,输入地址: http://localhost:9200,测试返回结果.
返回结果如下:
在这里插入图片描述

3. Kibana的安装

上面已经下载了kibanna直接解压 ,启动Kibana:bin目录下的kibana.bat
注意这个启动有点慢
用浏览器访问 http://localhost:5601
在这里插入图片描述
点这个小扳手之后就可以写相关代码了

4. ES中常见的概念

Elasticsearch 是面向文档型数据库,一条数据在这里就是一个文档。
为了方便理解,可以将 Elasticsearch 里存储文档数据和关系型数据库MySQL 存储数据的概念进行一个类比
在这里插入图片描述

 Index 可以看做一个库,
 Types 相当于表,
 Documents 则相当于表的行。
 
 Types 的概念已经被逐渐弱化, 
 Elasticsearch 6.X 中,一个 index 下已经只能包含一个type,
 Elasticsearch 7.X 中, Type 的概念已经被删除了。

5. ES常用API接口

在这里插入图片描述

5.1 基本操作

5.1.1 创建一个索引
#创建索引的第一种方式
#创建索引并往索引中添加一条文档
#结构 这里的1 表示id为1 若不加id 则为随机值
#  PUT /索引名称/类型名称/1
#  {
#    数据
#  }
PUT /qy152/student/1
{
  "name":"张三",
  "age":18
}

#创建索引的第二种方式
#创建索引并指定具体字段的数据类型
PUT /qy153
{
  "mappings": {
    "properties": {
      "name":{
        "type": "text"
      },
      "age":{
        "type": "integer"
      }
    }
  }
}

字段数据类型

字符串类型 :text、 keyword
	- text:支持分词,全文检索,支持模糊、精确查询,
		    不支持聚合,排序 操作;
		    text类型的最大支持的字符长度无限制,适合大字段存储; 
    - keyword:不进行分词,直接索引、支持模糊、支持精确匹配,支持聚合、排序操作。
    		   最大支持的长度为——32766个UTF-8 类型的字符,
    		   可以通过设置ignore_above指定自持字符长度,
    		   超过给定长度后的数据将不被索引,无法通过term精确匹配检索返回结果。

数值型 :long、Integer、short、byte、double、float、half float、scaled float
日期类型:date
布尔类型:boolean
二进制类型:binary
5.1.2 删除索引
#删除索引
DELETE /qy153
5.1.3 查询全部索引
GET /_cat/indices?v

在这里插入图片描述

5.1.4 查询具体索引结构
GET /qy151

在这里插入图片描述

5.1.5 添加文档
#指定id值  --该方式和建立索引一样
PUT /qy153/student/1
{
  "name":"李四",
  "age":25
}

#不指定id值
POST /qy153/student
{
  "name":"王五",
  "age":26
}
5.1.6 添加文档
# 删除文档 -- 根据id
DELETE /qy153/student/1
5.1.7 修改文档
#这种修改 必须指定所有列 若指定部分列 则原来的列会消失 如下图
PUT /qy153/student/2
{
  "name":"李四",
  "age":16
}


#只修改部分列
POST /qy153/student/3/_update
{
  "doc":{
    "name":"李四"
  }
}

在这里插入图片描述
在这里插入图片描述

	所以 
	 PUT /索引名称/类型名称/id值
  	{
  		 数据
	 }
	 这种结构可用于创建索引,添加文档,修改文档
	 若不存在则创建,若存在则修改
5.1.8 查询文档

查询的提交方式必须为GET

5.1.8.1 根据id查询
#GET /索引名称/类型名称/id值
GET /qy153/student/1

在这里插入图片描述

5.1.8.2 查询全部
#GET /索引名称/类型名称/_search
GET /qy153/student/_search

在这里插入图片描述

5.1.8.3 条件查询
	#GET /索引名称/类型名称/_search?q=字段名:值
	 #两种查询方式
	 #第一种 查询年龄为15的
	GET /qy153/student/_search?q=age:15
	
	#第二种查询 使用match匹配  (type也可以省略)  
	GET /qy153/student/_search
	{
	  "query": {
  	 	 "match": {
      		"age": 15
   		 	}
  		}
	}

在这里插入图片描述
在这里插入图片描述

5.1.8.4 范围(range)、匹配(match)、term(精准匹配)
# 数据准备 创建索引 插入三条数据
PUT /user/_doc/1 
{ 
  "name":"刘民谐", 
  "age": 18, 
  "desc": ["有趣","幽默","开朗"]
}
PUT /user/_doc/2
{
  "name":"马老师", 
  "age": 18,
  "desc": ["严谨","冷漠"]
}

PUT /user/_doc/3 
{ "name":"流油",
  "age": 3,
  "desc":["美丽","年轻","苗条"]
}
PUT /user/_doc/4 
{ 
  "name":"刘民X", 
  "age": 18, 
  "desc": ["有趣","幽默","开朗"]
}

GET /user

索引结构
在这里插入图片描述

可以看到name是keywords类型

Ⅰ. 范围匹配:range

range 查询可同时提供包含(inclusive)和不包含(exclusive)这两种范围表达式,
可供组合的选项如下:
	gt: > 大于(greater than)
	lt: < 小于(less than)
	gte: >= 大于或等于(greater than or equal to)
	lte: <= 小于或等于(less than or equal to)
#查询年龄大于3的人
GET /user/_search
{
  "query": {
    "range": {
      "age": {
       "gt":3
      }
    }
  }
}

在这里插入图片描述

Ⅱ. 匹配数组 match

match匹配会拆词 就是会将一个像搜索的词分为一个一个 
如:查询刘民谐这个人 它就会把刘民谐分为'刘' 、'民'、'谐' 然后去匹配
这里注意 汉字会被拆分 但是英文就仅仅是一个词 不会拆分
#查询刘民谐
GET /user/_search
{
  "query": {
    "match": {
      "name": "刘民谐"
    }
  }
}

在这里插入图片描述

Ⅲ. 精准匹配 term

精准匹配不会像match匹配,精准匹配不会拆词
所以查询刘民谐就只有一条记录
#查询刘民谐
GET /user/_search
{
  "query": {
    "term": {
      "name.keyword": "刘民谐"
    }
  }
}

在这里插入图片描述

5.1.8.5 查询部分列
	使用 _source


#查询部分列 查询年龄为18的人并且只查询其name和desc 使用_source
GET /user/_search
{
  "query":{
    "match": {
      "age": "18"
    }
  },
  "_source": ["name","desc"]
}

在这里插入图片描述

5.1.8.6 分页查询
#显示第二页的数据 每页显示1条
GET /user/_search
{
  "query":{
    "range": {
      "age":{
        "gt":16
      }
    }
  },
  "from": 1,
  "size":1
}

在这里插入图片描述

5.1.8.7 多条件查询

(1) 使用must ===>等价于and

GET /user/_search
{
  "query":{
    "bool": {
      "must": [
        {
          "match": {
            "name": "刘"
          }
        },
        {
          "match": {
            "age": "18"
          }
        }
      ]
    }
  }
}

在这里插入图片描述
(2) should ===>等价于 or

GET /user/_search
{
  "query":{
    "bool": {
      "should": [
        {
          "match": {
            "name": "刘"
          }
        },
        {
          "match": {
            "age": "18"
          }
        }
      ]
    }
  }
}

在这里插入图片描述
(3) must_not ===>等价于 ! 即取反

GET /user/_search
{
  "query":{
    "bool": {
      "must_not": [
        {
          "match": {
            "age": "18"
          }
        }
      ]
    }
  }
}

在这里插入图片描述

5.1.8.8 排序
#查询年龄大于16的人且按年龄降序排列
GET /user/_search
{
  "query":{
    "range": {
      "age":{
        "gt":2
      }
    }
  },
  "sort":[
    {
      "age":{
        "order":"desc"
      }
    }
  ],
  "from": 0,
  "size":10
}

在这里插入图片描述

5.1.8.9 高亮显示
#默认高亮
GET /user/_search
{
  "query": {
    "match": {
      "name": "刘"
    }
  },
  "highlight": {
    "fields": {
      "name":{}
    }
  }
  
  
}

在这里插入图片描述

#自定义高亮
GET /user/_search
{
  "query": {
    "match": {
      "name": "刘"
    }
  },
  "highlight": {
      "pre_tags": "<font color='red'>",
      "post_tags": "</font>",
      "fields": {
        "name":{}
      }
  }
}

在这里插入图片描述

6. springboot整合ES

(1)创建一个Springboot工程并加入相关的依赖 注意springboot的版本改为2.3.12.RELEASE

<dependencies>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.75</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <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>
    </dependencies>

(2) 创建一个配置,获取ES工具类对象。

@Configuration
public class ESConfig {

    //该对象可以对我们的ES进行相关的操作
    @Bean
    public RestHighLevelClient client(){
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost("127.0.0.1",9200,"http")));
        return client;
    }
}

(3)可进行相关对ES操作

6.1 ES相关操作

6.1.1 索引相关操作
//注入该对象
@Autowired
    private RestHighLevelClient client;
 /*创建索引*/
    @Test
    void test01() throws Exception{
        CreateIndexRequest createIndexRequest = new CreateIndexRequest("demo01");
        CreateIndexResponse createIndexResponse = client.indices().create(createIndexRequest, RequestOptions.DEFAULT);
        System.out.println(createIndexResponse.isAcknowledged( ));//查看是否创建成功
    }

    /*删除索引*/
    @Test
    void test02() throws Exception{
        DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("demo01");
        AcknowledgedResponse delete = client.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
        System.out.println(delete.isAcknowledged());
    }
    /*判断索引是否存在*/
    @Test
    void test03() throws Exception{
        GetIndexRequest getIndexRequest = new GetIndexRequest("demo01");
        boolean exists = client.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
        System.out.println(exists);
    }
6.1.2 文档相关操作

(1)添加文档

    /*添加文档*/
    @Test
    void test04() throws Exception{
        IndexRequest indexRequest = new IndexRequest("demo01");
        indexRequest.id("1"); //指定文档多的id
        //指定文档的内容:指定文档的json内容,XContentType xContentType:以什么格式
        indexRequest.source(JSON.toJSONString(new User("张三","北京",18)), XContentType.JSON);
        IndexResponse indexResponse = client.index(indexRequest, RequestOptions.DEFAULT);
        System.out.println(indexResponse.getResult());
    }
}

(2)查询文档–通过id

 /*通过id查询文档*/
    @Test
    void test05() throws Exception{
        GetRequest getRequest = new GetRequest("demo01");
        getRequest.id("1");
        GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
       //得到"_source"中的值
        String string = getResponse.getSourceAsString();
        //转为user对象
        User user = JSON.parseObject(string, User.class);
        System.out.println(user);

        //取出部分值 第二种写法
        Map<String, Object> sourceAsMap = getResponse.getSourceAsMap();
        System.out.println(sourceAsMap.get("address"));
    }

(3)判断文档是否存在

/*判断文档是否存在*/
    @Test
    void test06() throws Exception{
        GetRequest getRequest = new GetRequest("demo01");
        getRequest.id("1");
        boolean exists = client.exists(getRequest, RequestOptions.DEFAULT);
        System.out.println(exists);
    }

(4)删除文档

   /*删除文档*/
    @Test
    void test07() throws Exception{
        DeleteRequest deleteRequest = new DeleteRequest("demo01");
        deleteRequest.id("1");
        DeleteResponse deleteResponse = client.delete(deleteRequest, RequestOptions.DEFAULT);
        System.out.println(deleteResponse.getResult());
    }

(5)修改文档

/*修改文档*/
    @Test
    void test08() throws Exception{
        UpdateRequest updateRequest = new UpdateRequest("demo01","1");
        User user = new User();
        user.setName("李四");
        updateRequest.doc(JSON.toJSONString(user),XContentType.JSON);
        UpdateResponse update = client.update(updateRequest, RequestOptions.DEFAULT);
        System.out.println(update.getResult());
    }

(6)批量添加文档

/*批量添加文档*/
    @Test
    void test09() throws Exception{
        BulkRequest bulkRequest = new BulkRequest("demo01");
        List<User> list = new ArrayList<>();
        list.add(new User("1","张三","北京",18));
        list.add(new User("2","张三三","上海",19));
        list.add(new User("3","李四","北京",18));
        list.add(new User("4","李四四","上海",19));
        list.add(new User("5","王五","北京",18));
        list.add(new User("6","王五五","上海",19));
        /*用stream流循环添加*/
        list.stream().forEach(item->bulkRequest.add(new IndexRequest().id(item.getId()).source(JSON.toJSONString(item),XContentType.JSON)));
        BulkResponse bulk = client.bulk(bulkRequest, RequestOptions.DEFAULT);
        System.out.println(bulk.hasFailures());
        
    }

(7)条件查询

步骤:
	1. 搜索请求对象SearchRequest
	2. 构建一个条件对象SearchSourceBuilder
	3. 把条件对象放入搜索请求对象中
	4. 执行搜索功能
 /*条件查询*/
    @Test
    void test10() throws Exception{
        //1.搜索请求对象SearchRequest
        SearchRequest searchRequest = new SearchRequest("demo01");
        //2. 构建一个条件对象SearchSourceBuilder
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "王");
        //3. 把条件对象放入搜索请求对象中
        SearchSourceBuilder query = sourceBuilder.query(termQueryBuilder);
        
        SearchRequest source = searchRequest.source(query);
        //4. 执行搜索功能
        SearchResponse search = client.search(source, RequestOptions.DEFAULT);

        SearchHit[] hits = search.getHits().getHits();
        Arrays.stream(hits).forEach(item-> System.out.println(item.getSourceAsString()));
    }
}

在这里插入图片描述

    /*条件查询*/
    @Test
    void test11() throws Exception{
        //1.搜索请求对象SearchRequest
        SearchRequest searchRequest = new SearchRequest("demo01");
        //2. 构建一个条件对象SearchSourceBuilder
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        /*查询年龄大于18且姓名中含有王*/
        BoolQueryBuilder must = QueryBuilders
                                .boolQuery()
                                .must(QueryBuilders.rangeQuery("age").gt(17))
                                .must(QueryBuilders.matchQuery("name", "王"));
        //3. 把条件对象放入搜索请求对象中
        SearchSourceBuilder query = sourceBuilder.query(must);
       /*分页:从第一页开始每页显示1条*/
        sourceBuilder.from(0);
        sourceBuilder.size(10);
        /*降序排列  可不写SortOrder 默认升序*/
        sourceBuilder.sort("age", SortOrder.DESC);

        /*高亮*/
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        HighlightBuilder field = highlightBuilder.field("name");
        highlightBuilder.preTags("<font color='red'>");
        highlightBuilder.postTags("</font>");
        sourceBuilder.highlighter(highlightBuilder);

        SearchRequest source = searchRequest.source(query);
        //4. 执行搜索功能
        SearchResponse search = client.search(source, RequestOptions.DEFAULT);
        SearchHit[] hits = search.getHits().getHits();
        /*查询条数 搭配分页的时候使用*/
        System.out.println("总条数: "+search.getHits().getTotalHits().value);
        Arrays.stream(hits).forEach(item-> System.out.println(item.getSourceAsString()));
        Arrays.stream(hits).forEach(item-> System.out.println(item.getHighlightFields()));

    }
}

7.综合案例–爬取京东数据存储在es中并结合vue显示出来

(1)引入依赖
这里注意springboot的版本要低一点 <version>2.3.12.RELEASE</version>

 <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.11.3</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.75</version>
        </dependency>

(2)在kibana中建立索引

PUT /qy151-jd
{
  "mappings": {
    "properties": {
      "title":{
        "type": "text",
        "analyzer": "ik_max_word"
      },
      "price":{
        "type":"keyword"
      },
      "imgUrl":{
        "type": "keyword"
      }
    }
  },
  "settings": {
    "index.analysis.analyzer.default.type":"ik_max_word"
  }
}

(3)工具类准备

public class HtmlParseUtil {
    public static List<Product> parseJd(String keyword) throws Exception {
        String path="https://search.jd.com/Search?keyword="+keyword;
        //Document整个网页对象
        Document document = Jsoup.parse(new URL(path), 30000);
        Element j_goodsList = document.getElementById("J_goodsList");
        Elements li = j_goodsList.getElementsByTag("li");
        List<Product> list=new ArrayList<>();
        for (Element element:li){
            String pprice = element.getElementsByClass("p-price").eq(0).text();
            String pname = element.getElementsByClass("p-name").eq(0).text();
            String img = element.getElementsByTag("img").eq(0).attr("data-lazy-img");
            list.add(new Product(pname,pprice,img));
        }
        return list;
    }
}
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Result {
    private Integer code;
    private String msg;
    private Object data;
}

(4)实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Product {
    private String  title;
    private String  price;
    private String  imgUrl;
}

(5)controller层

@RestController
@RequestMapping("/product")
@CrossOrigin
public class ProductController {

    @Autowired
    private ProductService productService;

    @GetMapping ("/export/{keyword}")
    public Result export(@PathVariable String keyword) throws Exception{
            return productService.export(keyword);
    }


    @PostMapping("/search/{keyword}/{currentPage}/{pageSize}")
    public Result search(@PathVariable String keyword,@PathVariable Integer currentPage,@PathVariable Integer pageSize) throws Exception{
        return productService.search(keyword,currentPage,pageSize);
    }
}

(5)业务层service

@Service
public class ProductService {

    @Autowired
    private RestHighLevelClient restHighLevelClient;


    /*存储es中爬取的数据*/
    public Result export(String keyword) throws Exception {
        List<Product> productList = HtmlParseUtil.parseJd(keyword);
        //这里先在kibana上建立这个索引 上述代码存在
        BulkRequest bulkRequest = new BulkRequest("qy151-jd");
        //批量添加
        productList.stream().forEach(item->bulkRequest.add(new IndexRequest().source(JSON.toJSONString(item),XContentType.JSON)));
        BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
        if(bulk.hasFailures()){
            return new Result(5000,"批量添加失败",null);
        }else{
            return new Result(2000,"批量添加成功",null);
        }

    }

    /*从es中搜索缓存的数据*/
    public Result search(String keyword,Integer currentPage,Integer pageSize) throws Exception{
        SearchRequest searchRequest = new SearchRequest("qy151-jd");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //设置查询条件
        MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("title", keyword);
        searchSourceBuilder.query(queryBuilder);
        //设置分页
        searchSourceBuilder.from((currentPage-1)*pageSize);
        searchSourceBuilder.size(pageSize);

        //设置高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("title");
        highlightBuilder.preTags("<font style='color:red;font-size:14px;'>");
        highlightBuilder.postTags("</font>");
        searchSourceBuilder.highlighter(highlightBuilder);

        searchRequest.source(searchSourceBuilder);

        SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits hits = search.getHits();
        //总条数
        long totalHits = hits.getTotalHits().value;
        List<Map<String,Object>> result = new ArrayList<>();
        SearchHit[] hitsHits = hits.getHits();
        for(SearchHit hit:hitsHits){
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            //获取高亮字段
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            Text[] texts = highlightFields.get("title").getFragments();
            StringBuffer sb = new StringBuffer();
            Arrays.stream(texts).forEach(item->sb.append(item));
            //替换原来的title中值始得现在的值有高亮效果
            sourceAsMap.put("title",sb);
            //将总条数保存在map中
            sourceAsMap.put("total",totalHits);
            result.add(sourceAsMap);
        }
        return new Result(2000,"搜索成功",result);
    }
}


(6)前端页面

<template>
    <div class="page">
        <div id="app" class=" mallist tmall- page-not-market ">
            <!-- 头部搜索 -->
            <div id="header" class=" header-list-app">
                <div class="headerLayout">
                    <div class="headerCon ">
                        <!-- Logo-->
                        <h1 id="mallLogo">
                            <img src="../assets/logo.webp" width="115px" alt="">
                        </h1>
                        <div class="header-extra">
                            <!--搜索-->
                            <div id="mallSearch" class="mall-search">
                                <form name="searchTop" class="mallSearch-form clearfix">
                                    <fieldset>
                                        <legend>天猫搜索</legend>
                                        <div class="mallSearch-input clearfix">
                                            <div class="s-combobox" id="s-combobox-685">
                                                <div class="s-combobox-input-wrap">
                                                    <input v-model="keyword"  type="text" autocomplete="off" id="mq"
                                                           class="s-combobox-input"  aria-haspopup="true">
                                                </div>
                                            </div>
                                            <button type="submit" @click.prevent="searchKey" id="searchbtn">搜索</button>
                                        </div>
                                    </fieldset>
                                </form>
                                <ul class="relKeyTop">
                                    <li><a>老闫说Java</a></li>
                                    <li><a>老闫说前端</a></li>
                                    <li><a>老闫说Linux</a></li>
                                    <li><a>老闫说大数据</a></li>
                                    <li><a>老闫聊理财</a></li>
                                </ul>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <!-- 商品详情页面 -->
            <div id="content">
                <div class="main">
                    <!-- 品牌分类 -->
                    <form class="navAttrsForm">
                        <div class="attrs j_NavAttrs" style="display:block">
                            <div class="brandAttr j_nav_brand">
                                <div class="j_Brand attr">
                                    <div class="attrKey">
                                        品牌
                                    </div>
                                    <div class="attrValues">
                                        <ul class="av-collapse row-2">
                                            <li><a href="#"> 老闫说 </a></li>
                                            <li><a href="#"> Java </a></li>
                                        </ul>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </form>
                    <!-- 排序规则 -->
                    <div class="filter clearfix">
                        <a class="fSort fSort-cur">综合<i class="f-ico-arrow-d"></i></a>
                        <a class="fSort">人气<i class="f-ico-arrow-d"></i></a>
                        <a class="fSort">新品<i class="f-ico-arrow-d"></i></a>
                        <a class="fSort">销量<i class="f-ico-arrow-d"></i></a>
                        <a class="fSort">价格<i class="f-ico-triangle-mt"></i><i class="f-ico-triangle-mb"></i></a>
                    </div>
                    <!-- 商品详情 -->
                    <div class="view grid-nosku" >
                        <div class="product" v-for="item in results">
                            <div class="product-iWrap">
                                <!--商品封面-->
                                <div class="productImg-wrap">
                                    <a class="productImg">
                                        <img :src="item.imgUrl">
                                    </a>
                                </div>
                                <!--价格-->
                                <p class="productPrice">
                                    <em>{{item.price}}</em>
                                </p>
                                <!--标题-->
                                <p class="productTitle">
                                    <a v-html="item.title">  </a>
                                </p>
                                <!-- 店铺名 -->
                                <div class="productShop">
                                    <span>店铺: 老闫说Java </span>
                                </div>
                                <!-- 成交信息 -->
                                <p class="productStatus">
                                    <span>月成交<em>999笔</em></span>
                                    <span>评价 <a>3</a></span>
                                </p>
                            </div>
                        </div>
                    </div>

                    <el-pagination
                            @size-change="handleSizeChange"
                            @current-change="handleCurrentChange"
                            :current-page="currentPage"
                            :page-sizes="pageSizes"
                            :page-size="pageSize"
                            layout="total, sizes, prev, pager, next, jumper"
                            :total="total">
                    </el-pagination>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        name: "jd",
        data(){
             return {
                  keyword: '', // 搜索的关键字
                  results:[], // 后端返回的结果
                 pageSizes:[5,10,15,20],
                 currentPage:1,
                 pageSize:15,
                 total:0,
             }
        },
        methods:{
            /*分页*/
            handleSizeChange(val) {
                this.pageSize = val;
                this.searchKey();
            },
            handleCurrentChange(val) {
                this.currentPage = val;
                this.searchKey();
            },
            searchKey(){
                var keyword = this.keyword;
                this.$http.post('product/search/'+keyword+"/"+this.currentPage+"/"+this.pageSize).then(response=>{
                    console.log(response.data)
                    this.results=response.data.data;
                    this.total = response.data.data[0].total;
                })
            }
        }

    }
</script>

<style>
    /*** uncss> filename: http://localhost:9090/css/global.css ***/body,button,fieldset,form,h1,input,legend,li,p,ul{margin:0;padding:0}body,button,input{font:12px/1.5 tahoma,arial,"\5b8b\4f53";-ms-overflow-style:scrollbar}button,h1,input{font-size:100%}em{font-style:normal}ul{list-style:none}a{text-decoration:none}a:hover{text-decoration:underline}legend{color:#000}fieldset,img{border:0}#content,#header{margin-left:auto;margin-right:auto}html{zoom:expression(function(ele){ ele.style.zoom = "1"; document.execCommand("BackgroundImageCache", false, true); }(this))}@font-face{font-family:mui-global-iconfont;src:url(//at.alicdn.com/t/font_1401963178_8135476.eot);src:url(//at.alicdn.com/t/font_1401963178_8135476.eot?#iefix) format('embedded-opentype'),url(//at.alicdn.com/t/font_1401963178_8135476.woff) format('woff'),url(//at.alicdn.com/t/font_1401963178_8135476.ttf) format('truetype'),url(//at.alicdn.com/t/font_1401963178_8135476.svg#iconfont) format('svg')}#mallPage{width:auto;min-width:990px;background-color:transparent}#content{width:990px;margin:auto}#mallLogo{float:left;z-index:9;padding-top:28px;width:280px;height:64px;line-height:64px;position:relative}.page-not-market #mallLogo{width:400px}.clearfix:after,.clearfix:before,.headerCon:after,.headerCon:before{display:table;content:"";overflow:hidden}#mallSearch legend{display:none}.clearfix:after,.headerCon:after{clear:both}.clearfix,.headerCon{zoom:1}#mallPage #header{margin-top:-30px;width:auto;margin-bottom:0;min-width:990px;background:#fff}#header{height:122px;margin-top:-26px!important;background:#fff;min-width:990px;width:auto!important;position:relative;z-index:1000}#mallSearch #mq,#mallSearch fieldset,.mallSearch-input{position:relative}.headerLayout{width:990px;padding-top:26px;margin:0 auto}.header-extra{overflow:hidden}#mallSearch{float:right;padding-top:25px;width:390px;overflow:hidden}.mallSearch-form{border:solid #FF0036;border-width:3px 0 3px 3px}.mallSearch-input{background:#fff;height:30px}#mallSearch #mq{color:#000;margin:0;z-index:2;width:289px;height:20px;line-height:20px;padding:5px 3px 5px 5px;outline:0;border:none;font-weight:900;background:url(data:image/gif;base64,R0lGODlhAQADAJEAAObm5t3d3ff39wAAACH5BAAAAAAALAAAAAABAAMAAAICDFQAOw==) repeat-x;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}#mallSearch button{position:absolute;right:0;top:0;width:90px;border:0;font-size:16px;letter-spacing:4px;cursor:pointer;color:#fff;background-color:#FF0036;height:30px;overflow:hidden;font-family:'\5FAE\8F6F\96C5\9ED1',arial,"\5b8b\4f53"}#mallSearch .s-combobox{height:30px}#mallSearch .s-combobox .s-combobox-input:focus{outline:0}button::-moz-focus-inner{border:0;padding:0;margin:0}.page-not-market #mallSearch{width:540px!important}.page-not-market #mq{width:439px!important}
    /*** uncss> filename: http://localhost:9090/css/test.css ***/#mallSearch{float:none}.page-not-market #mallLogo{width:280px}.header-list-app #mallSearch{width:448px!important}.header-list-app #mq{width:347px!important}@media (min-width:1210px){#header .headerCon,#header .headerLayout,.main{width:1190px!important}.header-list-app #mallSearch{width:597px!important}.header-list-app #mq{width:496px!important}}@media (min-width:600px) and (max-width:800px) and (orientation:portrait){.pg .page{min-width:inherit!important}.pg #mallPage,.pg #mallPage #header{min-width:740px!important}.pg #header .headerCon,.pg #header .headerLayout,.pg .main{width:740px!important}.pg #mallPage #mallLogo{width:260px}.pg #header{min-width:inherit}.pg #mallSearch .mallSearch-input{padding-right:95px}.pg #mallSearch .s-combobox{width:100%!important}.pg #mallPage .header-list-app #mallSearch{width:auto!important}.pg #mallPage .header-list-app #mallSearch #mq{width:100%!important;padding:5px 0 5px 5px}}i{font-style:normal}.main,.page{position:relative}.page{overflow:hidden}@font-face{font-family:tm-list-font;src:url(//at.alicdn.com/t/font_1442456441_338337.eot);src:url(//at.alicdn.com/t/font_1442456441_338337.eot?#iefix) format('embedded-opentype'),url(//at.alicdn.com/t/font_1442456441_338337.woff) format('woff'),url(//at.alicdn.com/t/font_1442456441_338337.ttf) format('truetype'),url(//at.alicdn.com/t/font_1442456441_338337.svg#iconfont) format('svg')}::selection{background:rgba(0,0,0,.1)}*{-webkit-tap-highlight-color:rgba(0,0,0,.3)}b{font-weight:400}.page{background:#fff;min-width:990px}#content{margin:0!important;width:100%!important}.main{margin:auto;width:990px}.main img{-ms-interpolation-mode:bicubic}.fSort i{background:url(//img.alicdn.com/tfs/TB1XClLeAY2gK0jSZFgXXc5OFXa-165-206.png) 9999px 9999px no-repeat}#mallSearch .s-combobox{width:auto}::-ms-clear,::-ms-reveal{display:none}.attrKey{white-space:nowrap;text-overflow:ellipsis}.attrs{border-top:1px solid #E6E2E1}.attrs a{outline:0}.attr{background-color:#F7F5F5;border-color:#E6E2E1 #E6E2E1 #D1CCC7;border-style:solid solid dotted;border-width:0 1px 1px}.attr ul:after,.attr:after{display:block;clear:both;height:0;content:' '}.attrKey{float:left;padding:7px 0 0;width:10%;color:#B0A59F;text-indent:13px}.attrKey{display:block;height:16px;line-height:16px;overflow:hidden}.attrValues{position:relative;float:left;background-color:#FFF;width:90%;padding:4px 0 0;overflow:hidden}.attrValues ul{position:relative;margin-right:105px;margin-left:25px}.attrValues ul.av-collapse{overflow:hidden}.attrValues li{float:left;height:22px;line-height:22px}.attrValues li a{position:relative;color:#806F66;display:inline-block;padding:1px 20px 1px 4px;line-height:20px;height:20px;white-space:nowrap}.attrValues li a:hover{color:#ff0036;text-decoration:none}.brandAttr .attr{border:2px solid #D1CCC7;margin-top:-1px}.brandAttr .attrKey{padding-top:9px}.brandAttr .attrValues{padding-top:6px}.brandAttr .av-collapse{overflow:hidden;max-height:60px}.brandAttr li{margin:0 8px 8px 0}.brandAttr li a{text-overflow:ellipsis;overflow:hidden}.navAttrsForm{position:relative}.relKeyTop{padding:4px 0 0;margin-left:-13px;height:16px;overflow:hidden;width:100%}.relKeyTop li{display:inline-block;border-left:1px solid #ccc;line-height:1.1;padding:0 12px}.relKeyTop li a{color:#999}.relKeyTop li a:hover{color:#ff0036;text-decoration:none}.filter i{display:inline-block;overflow:hidden}.filter{margin:10px 0;padding:5px;position:relative;z-index:10;background:#faf9f9;color:#806f66}.filter i{position:absolute}.filter a{color:#806f66;cursor:pointer}.filter a:hover{color:#ff0036;text-decoration:none}.fSort{float:left;height:22px;line-height:20px;line-height:24px\9;border:1px solid #ccc;background-color:#fff;z-index:10}.fSort{position:relative}.fSort{display:inline-block;margin-left:-1px;overflow:hidden;padding:0 15px 0 5px}.fSort:hover,a.fSort-cur{color:#ff0036;background:#F1EDEC}.fSort i{top:6px;right:5px;width:7px;height:10px;line-height:10px}.fSort .f-ico-arrow-d{background-position:-22px -23px}.fSort-cur .f-ico-arrow-d,.fSort:hover .f-ico-arrow-d{background-position:-30px -23px}i.f-ico-triangle-mb,i.f-ico-triangle-mt{border:4px solid transparent;height:0;width:0}i.f-ico-triangle-mt{border-bottom:4px solid #806F66;top:2px}i.f-ico-triangle-mb{border-top:4px solid #806F66;border-width:3px\9;right:6px\9;top:12px}:root i.f-ico-triangle-mb{border-width:4px\9;right:5px\9}i.f-ico-triangle-mb,i.f-ico-triangle-mt{border:4px solid transparent;height:0;width:0}i.f-ico-triangle-mt{border-bottom:4px solid #806F66;top:2px}i.f-ico-triangle-mb{border-top:4px solid #806F66;border-width:3px\9;right:6px\9;top:12px}:root i.f-ico-triangle-mb{border-width:4px\9;right:5px\9}.view:after{clear:both;content:' '}.productImg,.productPrice em b{vertical-align:middle}.product{position:relative;float:left;padding:0;margin:0 0 20px;line-height:1.5;overflow:visible;z-index:1}.product:hover{overflow:visible;z-index:3;background:#fff}.product-iWrap{position:absolute;background-color:#fff;margin:0;padding:4px 4px 0;font-size:0;border:1px solid #f5f5f5;border-radius:3px}.product-iWrap *{font-size:12px}.product:hover .product-iWrap{height:auto;margin:-3px;border:4px solid #ff0036;border-radius:0;-webkit-transition:border-color .2s ease-in;-moz-transition:border-color .2s ease-in;-ms-transition:border-color .2s ease-in;-o-transition:border-color .2s ease-in;transition:border-color .2s ease-in}.productPrice,.productShop,.productStatus,.productTitle{display:block;overflow:hidden;margin-bottom:3px}.view:after{display:block}.view{margin-top:10px}.view:after{height:0}.productImg-wrap{display:table;table-layout:fixed;height:210px;width:100%;padding:0;margin:0 0 5px}.productImg-wrap a,.productImg-wrap img{max-width:100%;max-height:210px}.productImg{display:table-cell;width:100%;text-align:center}.productImg img{display:block;margin:0 auto}.productPrice{font-family:arial,verdana,sans-serif!important;color:#ff0036;font-size:14px;height:30px;line-height:30px;margin:0 0 5px;letter-spacing:normal;overflow:inherit!important;white-space:nowrap}.productPrice *{height:30px}.productPrice em{float:left;font-family:arial;font-weight:400;font-size:20px;color:#ff0036}.productPrice em b{margin-right:2px;font-weight:700;font-size:14px}.productTitle{display:block;color:#666;height:14px;line-height:12px;margin-bottom:3px;word-break:break-all;font-size:0;position:relative}.productTitle *{font-size:12px;font-family:\5FAE\8F6F\96C5\9ED1;line-height:14px}.productTitle a{color:#333}.productTitle a:hover{color:#ff0036!important}.productTitle a:visited{color:#551A8B!important}.product:hover .productTitle{height:14px}.productShop{position:relative;height:22px;line-height:20px;margin-bottom:5px;color:#999;white-space:nowrap;overflow:visible}.productStatus{position:relative;height:32px;border:none;border-top:1px solid #eee;margin-bottom:0;color:#999}.productStatus span{float:left;display:inline-block;border-right:1px solid #eee;width:39%;padding:10px 1px;margin-right:6px;line-height:12px;text-align:left;white-space:nowrap}.productStatus a,.productStatus em{margin-top:-8px;font-family:arial;font-size:12px;font-weight:700}.productStatus em{color:#b57c5b}.productStatus a{color:#38b}.productImg-wrap{position:relative}.product-iWrap{min-height:98%;width:210px}.view{padding-left:5px;padding-right:5px}.view{width:1023px}.view .product{width:220px;margin-right:33px}@media (min-width:1210px){.view{width:1210px;padding-left:5px;padding-right:5px}.view .product{width:220px;margin-right:20px}}@media (min-width:600px) and (max-width:800px) and (orientation:portrait){.view{width:775px;padding-left:5px;padding-right:5px}.view .product{width:220px;margin-right:35px}}.product{height:372px}.grid-nosku .product{height:333px}

</style>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Elasticsearch入门及整合springboot 的相关文章

  • python --根据windows窗口名称、进程pid打开窗口(pygetwindow详解)

    pygetwindow详解 简介 pygetwindow是一个Python库 xff0c 用于获取 操作和管理当前打开的窗口 它提供了一些常用的窗口操作方法 xff0c 包括获取窗口句柄 xff0c 获取窗口位置和大小 xff0c 移动和调
  • Redhat Linux advance Server V2.1无法进入桌面(转)

    Redhat Linux advance Server V2 xff11 无法进入桌面 转 64 more 64 在本地调试安装了个Redhat Linux advance Server V2 1 xff0c 一共有5张光盘 xff0c 我
  • Mac上类似于xshell的远程工具:finalshell 和 royal tsx

    FinalShell 国产 国产 国产 自己研发的 是一体化的的服务器 网络管理软件 不仅是ssh客户端 还是功能强大的开发 运维工具 充分满足开发 运维需求 特色功能 免费海外服务器远程桌面加速 ssh加速 本地化命令输入框 支持自动补全
  • css查找元素注意事项

    一 CSS ID 选择器查找元素 1 注意 xff1a 如果元素的ID不唯一 xff0c 或者是动态的 或者name以及linktext属性值也不唯一 我们就需要考虑用Xpath来查找元素了 xff0c 然后再对元素执行操作 不管用什么方式
  • OS2.3.7:多生产者,多消费者问题

    文章目录 0 问题描述1 问题分析2 实现3 总结 0 问题描述 桌子上有一只盘子 xff0c 每次只能向其中放入一个水果 爸爸专向盘子中放苹果 xff0c 妈妈专向盘子中放橘子 xff0c 儿子专等着吃盘子中的橘子 xff0c 女儿专等着
  • java 方法名类名命名规范

    一 命名规范 1 项目名全部小写 2 包名全部小写 3 类名首字母大写 xff0c 如果类名由多个单词组成 xff0c 每个单词的首字母都要大写 大驼峰 xff0c 如 xff1a public class MyFirstClass 4 变
  • Qt arm环境安装

    一 相关工作准备 Qt opensource 和 Qt everywhere 下载 链接 版本为5 9 8 arm linux gcc下载 链接 版本为4 8 3 tslib 下载 链接 版本为1 21 ps 可以不安装Qt opensou
  • STM32驱动ST7789V2 tft屏幕

    一 简介 本次教程使用的是1 54寸240 240像素的tft屏幕 xff0c 其接口协议为SPI协议 在使用的过程中仅需要四根数据即可驱动点亮屏幕 然后硬件使用的是STM32F103C8T6核心板 xff0c 用的是SPI2 一般购买屏幕
  • linux设置复杂度策略、登录超时处理功能

    1 在字符终端下 xff0c 实现某一用户连续错误登陆N次后 xff0c 就锁定该用户X分钟 pam tally2 执行 vi etc pam d login 在 PAM 1 0 下新起一行 xff0c 加入 auth required p
  • 飞控陀螺仪,磁力计,加速计,四元数姿态结算

    MPU6050主要包含陀螺仪和加速度计 陀螺仪主要测量角速度 xff0c 即可以测出某一时间段物体转过的角度 加速度计测量的是物体的加速度 xff0c 重力加速度即物体受重力作用的情况下具有的加速度 xff0c 物体静止时 xff0c 加速
  • 智慧物业管理系统(Springboot)

    开发工具 xff1a IDEA xff0c jdk1 8 数据库 xff1a mysql5 7 前台框架 xff1a layui 后端技术 xff1a springboot 项目描述 xff1a 1 前台住户登录 2 智慧物业管理后台 2
  • 北京大学2020公开课 AVL-Python实现代码

    class TreeNode def init self key val left 61 None right 61 None parent 61 None self key 61 key self payload 61 val self
  • Docker-2020详细教程<配合千锋Java学习营>

    Docker 2020详细教程 lt 配合千锋Java学习营 gt 2020 Docker最新超详细版教程通俗易懂 一 Docker介绍 1 下载Dcoker依的赖环境 想安装Docker xff0c 需要先将依赖的环境全部下载下来 xff
  • 使用阿里云部署Flask网页

    使用阿里云部署Flask网页 前端网页部署 阿里云apache CentOS 配置好Apache后 xff0c 将一整个html css js文件全部copy进 var www html目录下 之后就可以通过访问IP地址访问到你的index
  • MapReduce的个人理解

    MapReduce的个人理解 文章目录 MapReduce模型简介Map和Reduce函数这里给出一个简单实例 MapReduce的工作流程工作流程概述MapReduce的各个执行阶段 Shuffle过程详解Shuffle过程简介Map端的
  • Hadoop配置

    Hadoop配置 文章目录 Linux shell配置环境变量使环境变量生效Hadoop 集群安装配置到两台阿里云linux主机上Hadoop集群模式安装实验环境实验内容1 安装jdk2 下面来修改环境变量3 安装hadoop4 下面来修改
  • HDFS 的使用和管理

    HDFS 的使用和管理 文章目录 HDFS 的使用和管理实验环境实验内容实验步骤1 启动hadoop的hdfs相关进程2 用jps查看HDFS是否启动3 验证HDFS运行状态4 ls 命令5 put 命令6 moveFromLocal 命令
  • HDFS API操作

    HDFS API操作 实验环境 Linux Ubuntu 16 04 前提条件 xff1a 1 xff09 Java 运行环境部署完成 2 xff09 Hadoop 的单点部署完成 上述前提条件 xff0c 我们已经为你准备就绪了 实验内容
  • HBase的安装部署和使用

    HBase的安装部署和使用 文章目录 HBase的安装部署和使用实验环境实验内容实验步骤1 点击 34 命令行终端 34 xff0c 打开新的命令行窗口2 解压安装包3 更改文件夹名和所属用户4 设置HBASE HOME环境变量5 修改hb
  • 熟悉常用的HBase操作

    熟悉常用的HBase操作 文章目录 实验环境实验内容1 编程实现以下指定功能 xff0c 并用Hadoop提供的HBase Shell命令完成相同的任务 xff08 1 xff09 列出HBase所有的表的相关信息 xff0c 如表名 创建

随机推荐

  • Hive的安装部署和管理

    Hive的安装部署和管理 文章目录 实验环境实验内容实验步骤1 点击 34 命令行终端 34 xff0c 打开新窗口2 解压安装包3 更改文件夹名和所属用户4 设置HIVE HOME环境变量5 导入MySql jdbc jar包到hive
  • Hive数仓:使用桶表

    Hive数仓 xff1a 使用桶表 文章目录 Hive数仓 xff1a 使用桶表实验环境实验步骤1 点击 34 命令行终端 34 xff0c 打开新窗口2 启动MySQL3 指定元数据数据库类型并初始化Schema4 启动Hadoop5 启
  • python 获取当前文件路径

    一 Python 获取当前文件路径方法 sys path 0 获取文件当前工作目录路径 绝对路径 sys argv 0 获得模块所在的路径 由系统决定是否是全名 若显示调用python指令 xff0c 如python demo py xff
  • PySpark中的RDD基本操作

    PySpark中的RDD基本操作 课程性质 xff1a PySpark数据处理 文章目录 1 实验目标2 本次实验主要使用的 P y t h
  • PySpark中的RDD创建

    PySpark中的RDD创建 课程性质 xff1a PySpark数据处理 文章目录 1 实验目标2 本次实验主要使用的 P y t h
  • el-table-column的formatter的使用

    当后端返回来的数据格式需要再去处理 xff1b 可以使用formatter属性 lt el table column label 61 34 性别 34 align 61 34 center 34 formatter 61 34 genda
  • 提示“无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系“的解决方案

    使用sudo apt get install lt packgename gt 时出现提示无法修正错误 xff0c 因为您要求某些软件包保持现状 xff0c 就是它们破坏了软件包间的依赖关系 可以换个命令 sudo aptitude ins
  • aosp下载、编译、刷机和单编framework(android 12)

    我的设备 xff1a 咸鱼上买的pixel 3a 一 aosp下载 1 安装repo mkdir bin PATH 61 bin PATH curl sSL 39 https gerrit googlesource proxy ustclu
  • LAMP架构之mysql的安装部署

    mysql的安装部署 一 mysql编译安装1 编译过程 二 LAMP架构的部署 一 mysql编译安装 官网地址如下 xff0c 进入选择版本 xff1a https downloads mysql com archives commun
  • hexo博客绑定自己的域名

    hexo博客绑定自己的域名 学习网址1 学习网址2 学习网址3 一 购买域名 登录阿里云账号 控制台 搜索框输入域名 域名注册 输入需要注册的域名 xff08 查看是否被占用 xff09 加入购物车 xff08 显示不能备案的不可买 xff
  • SimpleDateFormat类 格式化日期

    功能 xff1a 格式化和解析日期 将Date类型的日期格式化成我们需要的日期类型一般是 字符串类型将字符串类的日期再转回来 用到两个方法 format Date date xff1a 将date型转换成特定格式的字符串 parse Str
  • 队列(Java实现)

    1 1应用场景 银行排队 xff1a 1 2基本介绍 特点 队列是一个有序列表 xff0c 可以用数组或是链表来实现 遵循先入先出的原则 即 xff1a 先存入队列的数据 xff0c 要先取出 后存入的要后取出 示意图 解释 MaxSize
  • IO字节流读取文本中文乱码

    1 1问题说明 我们都知道字符流适用于读取文本 xff0c 而字节流能读取文本 照片 视频等 xff0c 但是用字节流读取文本到我们程序的控制台中会出现中文乱码的情况 xff0c 如下图 我的文本中的数据是 生活很简单 xff0c 过了今天
  • glibc所安装的工具程序

    catchsegv 当程序发生segmentation fault的时候 用来建立一个 堆栈跟踪 gencat 建立消息列表 getconf 针对文件系统的指定变量显示其系统设置值 getent 从 系统管理数据库获取一个条目 glibcb
  • 单链表(java实现)

    1 1 链表 Linked List 介绍 链表是有序的列表 xff0c 但是它在内存中是存储如下 链表是以节点的方式来存储 是链式存储每个节点包含 data 域 xff0c next 域 xff1a 指向下一个节点 如图 xff1a 发现
  • prepareStatement的使用

    1 1prepareStatement解决sql注入的问题 span class token comment 演示sql注入的安全问题 span span class token keyword public span static voi
  • 动态sql

    1 什么是动态sql sql的内容是变化的 可以根据条件获取到不同的sql语句 主要是where部分发生变化 动态sql的实现 使用的是mybatis提供的标签 2 为什么使用动态sql 使用动态sql可以解决某些功能的使用 例如使用条件查
  • 分页插件--PageHelper

    mybatis的分页查询可以通过PageHelper插件实现 在数据库中我们使用分页查询的sql语句为 xff1a select from 表名 where 条件 limit page 1 pageSize pageSize page 当前
  • springboot框架

    1 什么是springboot框架 Spring是一个开源框架 xff0c Spring是于2003 年兴起的一个轻量级的Java 开发框架 xff0c 由Rod Johnson 在其著作 Expert One On One J2EE De
  • Elasticsearch入门及整合springboot

    1 Elasticsearch概述 1 1 搜索是什么 概念 xff1a 用户输入想要的关键词 xff0c 返回含有该关键词的所有信息 场景 xff1a 1 互联网搜索 xff1a 谷歌 百度 各种新闻首页 2 站内搜索 xff08 垂直搜