SpringCloud学习路线(10)——分布式搜索ElasticSeach基础

一、初识ES

(一)概念:

ES是一款开源搜索引擎,结合数据可视化【Kibana】、数据抓取【Logstash、Beats】共同集成为ELK(Elastic Stack),ELK被广泛应用于日志数据分析和实时监控等领域,ES是核心组件。

(二)作用: 高效查询搜索内容。

(三)发展史:

1、底层实现是 Lucene,一个Java语言的搜索引擎类库,Apache公司的Top产品之一,由DoungCutting 于 1999 年开发,官方地址:https://lucene.apache.org/
Lucene的优势: 易扩展(可二次开发)、高性能(基于倒排索引)
Lucene的缺点: 只限于Java开发、学习曲线陡峭、不支持水平扩展

2、2004年Shay Banon 基于 Lucene 开发了 Compass

3、2010年Shay Banon 重写了 Compass,重命名为 Elasticsearch
官方地址: https://www.elastic.co/cn/
ES的优势:

  • 支持分布式,支持水平扩展
  • 提供RESTful接口,可被任何语言调用

(四)ES对比其它搜索引擎的优势

根据搜索引擎技术使用频率排名,前三名是

  • ES:开源的分布式搜索引擎(常用)
  • Splunk:商业项目
  • Solr:Apache的开源资源引擎(常用)

(五)正向索引和倒排索引

1、正向索引
传统数据库(例如MySQL)采用的是正向索引。

  • 匹配内容进行逐条查询
  • 若不匹配则丢弃,若匹配放入结果集

2、倒排索引

ES使用倒排索引。

  • 文档(document): 每条数据就是一个文档
  • 词条(term): 文档按照语义分成的词语

倒排索引首先会把索引应用的字段分出各个词条,并且存储在 term-id 键值对表中,若分出的词条相同,则只将当前数据行的id记录到索引表的id字段中。

倒排索引的匹配数据顺序:

  • 搜索内容分词
  • 获得的词条去词条列表查询id
  • 根据文档id查询文档
  • 数据存入结果集

(六)ES与MySQL的概念对比

  • ES是面向文档存储的,可以是数据库中的一条商品数据,一个订单信息。
  • 文档数据会被序列化为json格式后存储在elasticsearch中。

1、ES文档

{
	"id": 1,
	“title”: "小米手机",
	"price": 2499
}
{
	"id": 2,
	“title”: "华为手机",
	"price": 4699
}
{
	"id": 3,
	“title”: "华为小米充电器",
	"price": 49
}
{
	"id": 4,
	“title”: "小米手环",
	"price": 299
}

2、ES索引

索引(Index) 是相同类型的文档集合(看文档结构就知道类型是否相同)。

3、MySQL与ES的概念对比

  • Table:Index —— 索引,就是文档的集合,类似库的表(Table)
  • Row:Document —— 文档,就是数据行,类似数据库中的行(Row),文档是JSON格式
  • Column:Field —— Field,就是JSON文档中的属性,类似数据库中的列(Column)
  • Schema:Mapping —— Mapping(映射)是索引中的文档约束,例如字段类型约束。类似于数据库的表结构(Schema)
  • SQL:DSL —— DSL 是 ES 提供的JSON风格的请求语句,用来才做ES,实现CRUD

4、架构

MySQL架构:擅长事务类型操作,确保数据的安全和一致性。(主要是写操作)
ES 架构:擅长海量数据的搜索、分析、计算。(主要是读操作)

(七)安装ES和kibana

为什么要安装kibana? 因为kibana可以协助我们操作ES。

1、部署单点 ES

(1)创建网络

因为我们还需要部署 kibana 容器,因此需要让es和kibana容器互联,需要创建一个网络。

docker network create es-net

在这里插入图片描述
(2)加载镜像

docker pull elasticsearch:7.12.1

在这里插入图片描述
(3)运行ES

运行docker命令,部署单点es:

# -e "cluster.name=es-docker-cluster:设置集群名称
# -e "ES_JAVA_OPTS=-Xms512m -Xmx512m": 设置堆内存大小
# -e "discovery.type=single-node": 配置部署类型为单点
# -v es-data:/usr/share/elasticsearch/data: ES数据挂载点
# -v es-plugins:/usr/share/elasticsearch/plugins: ES插件挂载点
# --network es-net: 容器加载到网络
# -p 9200:9200: 暴露的HTTP访问接口 
# -p 9300:9300: 暴露容器访问端口

docker run --name es \
	-e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
	-e "discovery.type=single-node" \
	-v es-data:/usr/share/elasticsearch/data \
	-v es-plugins:/usr/share/elasticsearch/plugins \
	--privileged \
	--network es-net \
	-p 9200:9200 \
	-p 9300:9300 \
	-d elasticsearch:7.12.1

在这里插入图片描述
访问9200端口

在这里插入图片描述

2、部署 kibana

docker pull kibana:7.12.1

在这里插入图片描述

# --network=es-net: 加入到ES的网络中
# -e ELASTICSEARCH_HOSTS=http://es:9200: 配置ES主机地址,因为在同一个网络中,所以可以直接用容器名访问ES
# -p 5601:5601: 端口映射配置
docker run --name kibana \
	-e ELASTICSEARCH_HOSTS=http://es:9200 \
	--network=es-net \
	-p 5601:5601 \
	-d kibana:7.12.1

在这里插入图片描述
访问Kibana控制台

在这里插入图片描述

DSL请求台

在这里插入图片描述

(八)分词器

ES在创建倒排索引时需要对文档分词;在搜索时,需要对用户输入内容分词,但默认的分词规则对中文处理并不好。

我们利用Kibana控制台做个中文测试:
在这里插入图片描述

中文分词器 IK

官网:https://github.com/medcl/elasticsearch-analysis-ik

1、部署 IK 分词器

在线安装可能会存在连接拒绝

#进入ES容器
docker exec -it es /bin/bash

#下载 IK分词器
./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.12.1/elasticsearch-analysis-ik-7.12.1.zip

#退出
exit

#重启容器
docker restart elasticsearch

离线安装 ik

1、下载 ik.7.12.1,zip
2、解压之后,传输到 elasticsearch-plugins 数据卷
3、重启docker

docker restart es

4、查看IK分词器加载成功

docker logs -f es

在这里插入图片描述
5、测试

  • ik_smart: 粗粒度区分,只拆分一次的方式进行解析。
    在这里插入图片描述

  • ik_max_word: 最细粒度拆分,最大可能的分出更多的词

在这里插入图片描述


(九)IK分词器的扩展词条和停用词条

IK分词器的底层基于词典进行匹配,若匹配到词典那么就直接拆分,若没有匹配到则不做拆分。

所以我们需要对IK分词进行扩展

1、修改 IK分词器 的 /config/IKAnalyzer.cfg.xml 文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
        <comment>IK Analyzer 扩展配置</comment>
        <!--用户可以在这里配置自己的扩展字典 -->
        <entry key="ext_dict">ext.dic</entry>
         <!--用户可以在这里配置自己的扩展停止词字典-->
        <entry key="ext_stopwords">stopword.dic</entry>
        <!--用户可以在这里配置远程扩展字典 -->
        <!-- <entry key="remote_ext_dict">words_location</entry> -->
        <!--用户可以在这里配置远程扩展停止词字典-->
        <!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>

2、创建 ext.dic 和 stopword.dic

这两个文件只是个文本文件,使用回车进行间隔,一个词一行。

这两个文件要配置在config目录下,不然读取不到,插件作者的词典也在config目录下。

3、重启docker

docker restart es

二、操作索引库

(一)mapping映射

常见的mapping属性

  • type: 字段数据类型,常见类型有
    • 字符串text(可分词的文本)、keyword(不可分词的文本)
    • 数值: byte、short、integer、long、float、double
    • 布尔: boolean
    • 日期: date
    • 对象: object
    • geo_point: 由经度和维度确认的点,例如"32.8138,120.58558"
    • geo_shape: 多个点复合的几何图形,例如一条直线LINESTRING(-77.06581831,-77.008463181)
  • index: 是否创建索引,默认为true
  • analyzer: 使用的分词器
  • properties: 该字段的子字段,例如对象中的属性
  • text: 分词文本

关于数组集合问题: mapping 支持单个类型能有多个。

(二)创建索引库

ES通过 RESTful 请求操作索引库、文档。请求内容用DSL语句来表示。

创建索引库和mapping 的DSL语法如下:

PUT /test
{
	"mappings": {
		"properties": {
				"info": {
					"type": "text"
					"analyzer": "ik_smart
				},
				"email": {
					"type": "keyword",
					"index": "false"
				},
				"name": {
     			   "type": "object",
					"properties": {
						"firstName": {
							"type": "keyword"
						},
						"lastName": {
							"type": "keyword"
						}
					}
				}
		}
	}
}

常见成功效果

{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "test"
}

这里还有个小技巧: 当我们需要多字段搜索可以使用 copy_to进行属性拷贝。

"all": {
	"type": "text",
	"analyzer: "ik_max_word"
},
"brand": {
	"type": "keyword",
	"copy_to": "all"
}

(三)查看、删除、修改索引库

1、查看索引库

GET /test

使用效果

{
  "test" : {
    "aliases" : { },
    "mappings" : {
      "properties" : {
        "email" : {
          "type" : "keyword",
          "index" : false
        },
        "info" : {
          "type" : "text",
          "analyzer" : "ik_smart"
        },
        "name" : {
          "properties" : {
            "firstName" : {
              "type" : "keyword"
            },
            "lastName" : {
              "type" : "keyword"
            }
          }
        }
      }
    },
    "settings" : {
      "index" : {
        "routing" : {
          "allocation" : {
            "include" : {
              "_tier_preference" : "data_content"
            }
          }
        },
        "number_of_shards" : "1",
        "provided_name" : "test",
        "creation_date" : "1690214456747",
        "number_of_replicas" : "1",
        "uuid" : "IIdXK-pATYOns4c8BDoaMw",
        "version" : {
          "created" : "7120199"
        }
      }
    }
  }
}

2、删除索引库

DELETE /test

使用效果

删除成功效果
{
  "acknowledged" : true
}

再次查询索引库
{
  "error" : {
    "root_cause" : [
      {
        "type" : "index_not_found_exception",
        "reason" : "no such index [test]",
        "resource.type" : "index_or_alias",
        "resource.id" : "test",
        "index_uuid" : "_na_",
        "index" : "test"
      }
    ],
    "type" : "index_not_found_exception",
    "reason" : "no such index [test]",
    "resource.type" : "index_or_alias",
    "resource.id" : "test",
    "index_uuid" : "_na_",
    "index" : "test"
  },
  "status" : 404
}

3、修改索引库(只能添加字段)

PUT /test/_mapping
{
	"properties": {
		"age": {
			"type": "integer
		}
	}
}

使用效果

新增成功
{
  "acknowledged" : true
}
再次查询/test索引库
{
  "test" : {
    "aliases" : { },
    "mappings" : {
      "properties" : {
        "age" : {
          "type" : "integer"
        },
        "email" : {
          "type" : "keyword",
          "index" : false
        },
        "info" : {
          "type" : "text",
          "analyzer" : "ik_smart"
        },
        "name" : {
          "properties" : {
            "firstName" : {
              "type" : "keyword"
            },
            "lastName" : {
              "type" : "keyword"
            }
          }
        }
      }
    },
    "settings" : {
      "index" : {
        "routing" : {
          "allocation" : {
            "include" : {
              "_tier_preference" : "data_content"
            }
          }
        },
        "number_of_shards" : "1",
        "provided_name" : "test",
        "creation_date" : "1690214957185",
        "number_of_replicas" : "1",
        "uuid" : "HeoHP6GYS-uovI1DQyxEsg",
        "version" : {
          "created" : "7120199"
        }
      }
    }
  }
}

三、文档操作

(一)新增文档

POST /test/_doc/1
{
	"info": "Java是最好的语言",
	"age": 18,
	"email": :"zengoo@163.com",
	"name": {
		"firstName": "Zengoo",
		"lastName": "En"
	}
}

使用效果

{
  "_index" : "test",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}

(二)删除文档

DELETE /test/_doc/1

使用效果

删除成功
{
  "_index" : "test",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 2,
  "result" : "deleted",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 1,
  "_primary_term" : 1
}

再次查询
{
  "_index" : "test",
  "_type" : "_doc",
  "_id" : "1",
  "found" : false
}

(三)修改文档

PUT /test/_doc/1
{
	"info": "这是我的ES拆分Demo"
}

使用效果

修改成功
{
  "_index" : "test",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 2,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 3,
  "_primary_term" : 1
}

再次查询
{
  "_index" : "test",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 2,
  "_seq_no" : 3,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "info" : "这是我的ES拆分Demo"
  }
}

我们可以看到直接使用PUT进行修改,会直接覆盖原有的文档。

所以我们使用第二种修改方法。

POST /test/_update/1
{
	"doc": {
		"info": "这是我的ES拆分Demo"
	}
}

使用效果

更新成功
{
  "_index" : "test",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 11,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 12,
  "_primary_term" : 1
}

查询文档
{
  "_index" : "test",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 11,
  "_seq_no" : 12,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "info" : "这是我的ES拆分Demo",
    "age" : 18,
    "email" : "zengoo@163.com",
    "name" : {
      "firstName" : "Zengoo",
      "lastName" : "En"
    }
  }
}

(四)查询文档

GET /test/_doc/1

使用效果

{
  "_index" : "test",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "_seq_no" : 0,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "info" : "Java是最好的语言",
    "age" : 18,
    "email" : "zengoo@163.com",
    "name" : {
      "firstName" : "Zengoo",
      "lastName" : "En"
    }
  }
}

四、RestClient操作索引库

(一)RestClient

ES官方提供了不同语言的ES客户端,这些客户端的本质是组装DSL语句,通过HTTP请求发送给ES。
官方文档: https://www.elastic.co/guide/en/elasticsearch/client/index.html

(二)安装RestClient

安装RestHighLevelClient依赖

<dependency>
	<groupId>org.elasticsearch.client</groupId>
	<artifactId>elasticsearch-rest-hight-level-client</artifatId>
</dependency>

覆盖默认的ES版本

<properties>
	<elasticsearch.version>7.12.1</elasticsearch.version>
</properties>

初始化RestHighLevelClient

RestHightLevelClient client = new RestHighLevelClient(RestClient.builder(HttpHost.create("http://192.168.92.131:9200")));

(三)RestClient操作索引库

创建索引库

//1、创建Request对象
CreateIndexRequest request = new CreateIndexRequest("test");
//2、请求参数,
//MAPPING_TEMPLATE 是静态常量字符串,描述的是自定义的创建索引库的DSL语句
//XContentType.JSON 是指定DSL语句以JSON格式化
request.source(MAPPING_TEMPLATE, XContentType.JSON);
//3、发起请求
//indices, 返回对象中包含的所有索引库操作方法
//RequestOptions.DEFAULT, 默认请求头
client.indices().create(request, RequestOptions.DEFAULT);

删除索引库

CreateIndexRequest request = new CreateIndexRequest("test");
client.indices().delete(request, RequestOptions.DEFAULT);

查询索引库存在状态

CreateIndexRequest request = new CreateIndexRequest("test");
boolean status = client.indices().exists(request, RequestOptions.DEFAULT);

(四)RestClient操作数据文档

创建文档

//根据ID查询数据, hotelService的自定义的方法getById
Hotel hotel = hotelService.getById(1L);
//转换类型,由于数据库类型与DSL类型有差异,所以需要定义一个转换类进行属性转换,即转换类构造器改造实体类。
HotelDoc hotelDoc = new HotelDoc(hotel);
//1、创建Request对象
IndexRequest request = new IndexRequest("test").id(hotel.getId().toString());
//2、准备JSON文档, 通过fastjson快速转换成json格式文本
request.source(JSON.toJSONString(hotelDoc, XContentType.JSON);
//3、发送请求
//index, 就是发送请求的那个索引
client.index(request, RequestOptions.DEFAULT);

查询文档

//1、创建request对象
GetRequest request = new GetRequest("test").id("1");
//2、发送请求,得到结果
GetResponse response = client.get(request, RequestOptions.DEFAULT);
//3、解析结果
String json = response.getSourceAsString();
System.out.println(JSON.parseObject(json, HotelDoc.class));

删除文档

//1、创建request对象
DeleteRequest request = new DeleteRequest("test").id("1");
//2、发送请求,得到结果
client.delete(request, RequestOptions.DEFAULT);

修改文档

方式一:全量修改

方式二:局部修改

//1、创建Request对象
UpdateRequest request = new UpdateRequest("test","1");
//2、准备参数,每两个参数为一对
request.doc(
	"age": 18,
	"name": "Rose"
);
//3、更新文档
client.update(request, RequestOptions.DEFAULT);

批量导入文档

使用思路

1、通过mybatis查询数据库数据
2、实体类数据转换成文档类型数据
3、RestClient利用Bulk批处理

//1、创建Bulk请求
BulkRequest request = new BulkRequest();

//2、添加批量处理请求
for(Hotel hotel: hotels){
	HotelDoc hotelDoc = new HotelDoc(hotel);
	request.add(new IndexRequest("hotel").id(hotel.getId().toString()).source(JSON.tJSONString(hotelDoc),XContentType.JSON));
}

//3、发起请求
client.bulk(request, RequestOptions.DEFAULT);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/44996.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【数据挖掘】将NLP技术引入到股市分析

一、说明 在交易中实施的机器学习模型通常根据历史股票价格和其他定量数据进行训练&#xff0c;以预测未来的股票价格。但是&#xff0c;自然语言处理&#xff08;NLP&#xff09;使我们能够分析财务文档&#xff0c;例如10-k表格&#xff0c;以预测股票走势。 二、对自然语言处…

2023年Q2京东环境电器市场数据分析(京东数据产品)

今年Q2&#xff0c;环境电器市场中不少类目表现亮眼&#xff0c;尤其是以净水器、空气净化器、除湿机等为代表的环境健康电器。此外&#xff0c;像冷风扇这类具有强季节性特征的电器也呈现出比较好的增长态势。 接下来&#xff0c;结合具体数据我们一起来分析Q2环境电器市场中…

【已解决】jupyter notebook里已经安装了第三方库,还是提示导入失败

在jupyter notebook中运行Python代码&#xff0c;明明已经安装了第三方库&#xff0c;还是提示导入失败。 以导入pandas库为例&#xff0c;其他库同理&#xff1a; 报错代码&#xff1a; import pandas报错原因&#xff1a; 电脑上存在多个python运行环境&#xff08;比如&a…

JavaEE——Spring中存取Bean的注解

目录 一、存储Bean对象 1、定义 2、存储方式 &#xff08;1&#xff09;、类注解 【1】、Controller&#xff08;控制器存储&#xff09; 【2】、Service&#xff08;服务存储&#xff09; 【3】、Repository&#xff08;仓库存储&#xff09; 【4】、Component&#xf…

[JAVAee]线程安全

目录 线程安全的理解 线程不安全的原因 ①非原子性 ②可见性 ③代码重排序 体会何为不安全的线程 保证线程安全 一个代码在多线程的环境下就很容易出现错误. 线程安全的理解 线程安全是什么呢?通俗的来讲,线程安全就是在多线程的环境下,代码的结果是符合我们预期的,就…

Kafka基础架构与核心概念

Kafka简介 Kafka是由Apache软件基金会开发的一个开源流处理平台&#xff0c;由Scala和Java编写。Kafka是一种高吞吐量的分布式发布订阅消息系统&#xff0c;它可以处理消费者在网站中的所有动作流数据。架构特点是分区、多副本、多生产者、多订阅者&#xff0c;性能特点主要是…

VisualStudio如何进行插件开发?

文章目录 0.引言1.工具准备2.创建插件项目&#xff08;VSIX&#xff09;3.自定义VSIX属性4.创建一个command命令5.设置command名称6.编写command功能7.调试插件8.安装插件 0.引言 使用Visual Studio插件可以极大地提升开发效率、提供更好的集成环境、丰富扩展生态系统、方便调试…

python报错:‘unicodeescape‘ codec can‘t decode bytes解决办法

参考:https://blog.csdn.net/shuyudexiaowu/article/details/108771481 我的代码是这样&#xff1a; 错误原因是&#xff1a;python把字符串中的反斜杠“ \ ”当成了字符串的一部分&#xff0c;而不是反斜杠。 解决办法两个&#xff1a; 1、在文件目录前加个 r&#xff0c;&…

线性神经网路——线性回归随笔【深度学习】【PyTorch】【d2l】

文章目录 3.1、线性回归3.1.1、PyTorch 从零实现线性回归3.1.2、简单实现线性回归 3.1、线性回归 线性回归是显式解&#xff0c;深度学习中绝大多数遇到的都是隐式解。 3.1.1、PyTorch 从零实现线性回归 %matplotlib inline import random import torch #d2l库中的torch模块&a…

PCL 计算点云AABB包围盒

目录 一、算法原理二、代码实现1、直接计算2、惯性矩法三、结果展示本文由CSDN点云侠原创。爬虫自重,把自己当个人。 一、算法原理 AABB包围盒又称了 轴对齐包围盒,是点云包围盒里最简单的一种,其计算方法也极其简单,看代码即可理解!!!目前PCL中有直接计算和基于惯性偏…

Xshell使用sftp传输文件

单击工具栏新建回话图标&#xff0c;在弹出的新建回话窗口中协议选择SFTP&#xff0c;输入主机名或ip地址&#xff0c;端口号22&#xff0c;单击连接&#xff0c;输入用户名和密码完成创建连接。 本地/远程目录设置&#xff1a;新建会话时在下图中SFTP中设置文件上传下载的本地…

TOOD Task-aligned One-stage Object Detection 论文学习

1. 解决了什么问题&#xff1f; 目标检测通过多任务学习的方式&#xff0c;协同优化目标的分类和定位。分类任务会学习目标的判别特征&#xff0c;关注于目标的显著性或关键区域&#xff0c;而定位任务则学习准确地定位目标的边界。因为定位和分类的学习机制不同&#xff0c;这…

DP学习第三篇之不同路径

DP学习第三篇之不同路径 62. 不同路径 - 力扣&#xff08;LeetCode&#xff09; 一.题目解析 二. 算法原理 状态表示 tips: 经验题目要求。以[i,j]位置为结尾&#xff0c;。。。 dp[i][j]: 走到[i, j]位置时&#xff0c;一共多少种路径 状态转移方程 tips: 用之前或之后的状…

Visual Studio Code安装详细教程

win电脑可以打开该网址 vs官方下载网站 点击这里免费下载 下载下来是一个安装程序&#xff0c;直接以管理员身份运行即可 我同意安装&#xff0c;然后选择D盘的一个空间进行安装 然后点击下一步 安装如图所示勾选&#xff0c;点击下一步 点击安装 等待安装完成即可 打开…

Electron 学习_BrowserWindow

BrowserWindow创建并控制浏览器窗口(主进程) 条件&#xff1a;在 app 模块 emitted ready 事件之前&#xff0c;您不能使用此模块。 1.在加载页面时&#xff0c;渲染进程第一次完成绘制时&#xff0c;如果窗口还没有被显示&#xff0c;渲染进程会发出 ready-to-show 事件 。 在…

前端(九)——探索微信小程序、Vue、React和Uniapp生命周期

&#x1f642;博主&#xff1a;小猫娃来啦 &#x1f642;文章核心&#xff1a;探索微信小程序、Vue、React和Uniapp生命周期 文章目录 微信小程序、Vue、React和Uniapp的基本定义和应用领域微信小程序生命周期生命周期概述页面生命周期应用生命周期组件和API的生命周期钩子 Vu…

失去中国市场的三星继续称霸全球,中国手机的份额反而进一步下降了

市调机构canalys公布了二季度全球手机市场的数据&#xff0c;数据显示三星、苹果的市场份额保持稳定并位居全球前二&#xff0c;三星的表现显然让人称奇&#xff0c;一直被唱衰&#xff0c;却一直都稳稳占据全球手机市场第一名。 从Canalys公布的数据可以看到&#xff0c;三星以…

从零开始学习自动驾驶路径规划-环境配置

从零开始学习自动驾驶路径规划-环境配置 前面&#xff0c;每个人遇到的问题不一样&#xff0c;这里记录了配置步骤和目前遇到的问题&#xff0c;会持续更新报错解决方法。配置时有报错请认真看报错经验 环境配置步骤&#xff08;18.04和20.04都可以&#xff0c;有些问题没遇到…

vue中重新获取数据导致页面加长,要求在页面更新之后浏览器滚动条滚动到之前浏览记录的位置。以及获取当前页面中是哪个元素产生滚动条的方法。

目前的页面样式为&#xff1a; 代码是&#xff1a; <section id"detailSection"><el-tableref"multipleTable":data"logDetailList"style"width: 650px;margin:20px auto;"id"dialogDetail":show-header"fals…

【NLP】图解变压器(transformer)

一、说明 在这篇文章中&#xff0c;我们将看看 The Transformer——一个利用注意力来提高这些模型训练速度的模型。转换器在特定任务中优于谷歌神经机器翻译模型。然而&#xff0c;最大的好处来自变压器如何适应并行化。事实上&#xff0c;谷歌云建议使用The Transformer作为参…