最新要闻
- 15日起内地赴港澳签注办理更便捷 端午赴港澳机票较五一降三成|环球视点
- 索尼最强旗舰!Xperia 1 V发布:8999元起
- 4月SUV销量排名:比亚迪双星无敌!燃油车苦苦挣扎
- 《种地吧》下期精彩:后陡门篮球赛主打团结 种地团直面成长阵痛-当前资讯
- 孟羽童视频回应离职格力:下一步将申请读研|环球观点
- 2999元!佳能发布掌上Vlog机PowerShot V10 比手机还小巧
- 焦点热讯:索尼放大招 Xperia 1 V用上双层晶体管传感器:画质媲美全画幅相机
- 天玑9200+正式发布!解决旗舰用户三大痛点 带来顶级游戏性能体验 世界新消息
- 黑寡妇毒杀亲夫
- 【天天热闻】手动挡正确停止和关闭发动机 以及关闭发动机钥匙的步骤
- 【独家】泰州姜堰:绿色能源清风吹拂一座城
- 环球新消息丨借鉴新加坡经验 深圳地铁拟推行早起上班优惠价:缓解早高峰拥挤
- 正式超越日本!一季度中国成全球第一大汽车出口国 天天速看料
- 三层防护 稳健医用外科口罩便宜了:3盒150只到手21.8元
- 全球快播:年内最大降幅?国内油价或即将大幅度下调 就在5月16日
- 微信开启“带货时代”:公众号今日起也能带货了
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
6000+字讲透ElasticSearch 索引设计
ElasticSearch 索引设计
在MySQL中数据库设计非常重要,同样在ES中数据库设计也是非常重要的
【资料图】
概述
我们创建索引就像创建表结构一样,必须非常慎重的,索引如果创建不好后面会出现各种各样的问题
索引设计的重要性
索引创建后,索引的分片只能通过
_split
和_shrink
接口对其进行成倍的增加和缩减
主要是因为es的数据是通过_routing
分配到各个分片上面的,所以本质上是不推荐去改变索引的分片数量的,因为这样都会对数据进行重新的移动。
还有就是索引只能新增字段,不能对字段进行修改和删除,缺乏灵活性,所以每次都只能通过_reindex
重建索引了,还有就是一个分片的大小以及所以分片数量的多少严重影响到了索引的查询和写入性能,所以可想而知,设计一个好的索引能够减少后期的运维管理和提高不少性能,所以前期对索引的设计是相当的重要的。
基于时间的Index设计
Index设计时要考虑的第一件事,就是基于时间对Index进行分割,即每隔一段时间产生一个新的Index
这样设计的目的
因为现实世界的数据是随着时间的变化而不断产生的,切分管理可以获得足够的灵活性和更好的性能
如果数据都存储在一个Index中,很难进行扩展和调整,因为Elasticsearch中Index的某些设置在创建时就设定好了,是不能更改的,比如Primary Shard的个数。
而根据时间来切分Index,则可以实现一定的灵活性,既可以在数据量过大时及时调整Shard个数,也可以及时响应新的业务需求。
大多数业务场景下,客户对数据的请求都会命中在最近一段时间上,通过切分Index,可以尽可能的避免扫描不必要的数据,提高性能。
时间间隔
根据上面的分析,自然是时间越短越能保持灵活性,但是这样做就会导致产生大量的Index,而每个Index都会消耗资源来维护其元信息的,因此需要在灵活性、资源和性能上做权衡
- 常见的间隔有小时、天、周和月:先考虑总共要存储多久的数据,然后选一个既不会产生大量Index又能够满足一定灵活性的间隔,比如你需要存储6个月的数据,那么一开始选择“周”这个间隔就会比较合适。
- 考虑业务增长速度:假如业务增长的特别快,比如上周产生了1亿数据,这周就增长到了10亿,那么就需要调低这个间隔来保证有足够的弹性能应对变化。
如何实现分割
切分行为是由客户端(数据的写入端)发起的,根据时间间隔与数据产生时间将数据写入不同的Index中,为了易于区分,会在Index的名字中加上对应的时间标识
创建新Index这件事,可以是客户端主动发起一个创建的请求,带上具体的Settings、Mappings等信息,但是可能会有一个时间错位,即有新数据写入时新的Index还没有建好,Elasticsearch提供了更优雅的方式来实现这个动作,即Index Template
分片设计
所谓分片设计,就是如何设定主分片的个数
看上去只是一个数字而已,也许在很多场景下,即使不设定也不会有问题(ES7默认是1个主分片一个副本分片),但是如果不提前考虑,一旦出问题就可能导致系统性能下降、不可访问、甚至无法恢复,换句话说,即使使用默认值,也应该是通过足够的评估后作出的决定,而非拍脑袋定的。
限制分片大小
单个Shard的存储大小不超过30GB
Elastic专家根据经验总结出来大家普遍认为30GB是个合适的上限值,实践中发现单个Shard过大(超过30GB)会导致系统不稳定。
其次,为什么不能超过30GB?主要是考虑Shard Relocate过程的负载,我们知道,如果Shard不均衡或者部分节点故障,Elasticsearch会做Shard Relocate,在这个过程中会搬移Shard,如果单个Shard过大,会导致CPU、IO负载过高进而影响系统性能与稳定性。
评估分片数量
单个Index的
Primary Shard个数 = k * 数据节点个数
在保证第一点的前提下,单个Index的Primary Shard个数不宜过多,否则相关的元信息与缓存会消耗过多的系统资源,这里的k,为一个较小的整数值,建议取值为1,2等,整数倍的关系可以让Shard更好地均匀分布,可以充分的将请求分散到不同节点上。
小索引设计
对于很小的Index,可以只分配1~2个Primary Shard的
有些情况下,Index很小,也许只有几十、几百MB左右,那么就不用按照第二点来分配了,只分配1~2个Primary Shard是可以,不用纠结。
使用索引模板
就是把已经创建好的某个索引的参数设置(settings)和索引映射(mapping)保存下来作为模板,在创建新索引时,指定要使用的模板名,就可以直接重用已经定义好的模板中的设置和映射
Elasticsearch基于与索引名称匹配的通配符模式将模板应用于新索引,也就是说通过索引进行匹配,看看新建的索引是否符合索引模板,如果符合,就将索引模板的相关设置应用到新的索引,如果同时符合多个索引模板呢,这里需要对参数priority进行比较,这样会选择priority大的那个模板进行创建索引。
在创建索引模板时,如果匹配有包含的关系,或者相同,则必须设置priority为不同的值,否则会报错,索引模板也是只有在新创建的时候起到作用,修改索引模板对现有的索引没有影响,同样如果在索引中设置了一些设置或者mapping都会覆盖索引模板中相同的设置或者mapping
索引模板的用途
索引模板一般用在时间序列相关的索引中。
也就是说, 如果你需要每间隔一定的时间就建立一次索引,你只需要配置好索引模板,以后就可以直接使用这个模板中的设置,不用每次都设置settings和mappings.
创建索引模板
COPYPUT _index_template/logstash-village{ "index_patterns": [ "logstash-village-*" // 可以通过"logstash-village-*"来适配创建的索引 ], "template": { "settings": { "number_of_shards": "3", //指定模板分片数量 "number_of_replicas": "2" //指定模板副本数量 }, "aliases": { "logstash-village": {} //指定模板索引别名 }, "mappings": { //设置映射 "dynamic": "strict", //禁用动态映射 "properties": { "@timestamp": { "type": "date", "format": "strict_date_optional_time||epoch_millis||yyyy-MM-dd HH:mm:ss" }, "@version": { "doc_values": false, "index": "false", "type": "integer" }, "name": { "type": "keyword" }, "province": { "type": "keyword" }, "city": { "type": "keyword" }, "area": { "type": "keyword" }, "addr": { "type": "text", "analyzer": "ik_smart" }, "location": { "type": "geo_point" }, "property_type": { "type": "keyword" }, "property_company": { "type": "text", "analyzer": "ik_smart" }, "property_cost": { "type": "float" }, "floorage": { "type": "float" }, "houses": { "type": "integer" }, "built_year": { "type": "integer" }, "parkings": { "type": "integer" }, "volume": { "type": "float" }, "greening": { "type": "float" }, "producer": { "type": "keyword" }, "school": { "type": "keyword" }, "info": { "type": "text", "analyzer": "ik_smart" } } } }}
模板参数
下面是创建索引模板的一些参数
参数名称 | 参数介绍 |
---|---|
index_patterns | 必须配置,用于在创建期间匹配索引名称的通配符(*)表达式数组 |
template | 可选配置,可以选择包括别名、映射或设置配置 |
composed_of | 可选配置,组件模板名称的有序列表。组件模板按指定的顺序合并,这意味着最后指定的组件模板具有最高的优先级 |
priority | 可选配置,创建新索引时确定索引模板优先级的优先级。选择具有最高优先级的索引模板。如果未指定优先级,则将模板视为优先级为0(最低优先级) |
version | 可选配置,用于外部管理索引模板的版本号 |
_meta | 可选配置,关于索引模板的可选用户元数据,可能有任何内容 |
映射配置
上面我们配置了映射模板,但是我们用到了映射,下面我们说下映射
什么是映射
在创建索引时,可以预先定义字段的类型(映射类型)及相关属性
数据库建表的时候,我们DDL依据一般都会指定每个字段的存储类型,例如:varchar、int、datetime等,目的很明确,就是更精确的存储数据,防止数据类型格式混乱,在Elasticsearch中也是这样,创建索引的时候一般也需要指定索引的字段类型,这种方式称为映射(Mapping)
被动创建(动态映射)
此时字段和映射类型不需要事先定义,只需要存在文档的索引,当向此索引添加数据的时候当遇到不存在的映射字段,ES会根据数据内容自动添加映射字段定义。
动态映射规则
使用动态映射的时候,根据传递请求数据的不同会创建对应的数据类型
数据类型 | Elasticsearch 数据类型 |
---|---|
null | 不添加任何字段 |
true或者false | boolean类型 |
浮点数据 | float类型 |
integer数据 | long类型 |
object | object类型 |
array | 取决于数组中的第一个非空值的类型。 |
string | 如果此内容通过了日期格式检测,则会被认为是date数据类型 如果此值通过了数值类型检测则被认为是double或者long数据类型 带有关键字子字段会被认为一个text字段 |
禁止动态映射
一般生产环境下需要禁用动态映射,使用动态映射可能出现以下问题
- 造成集群元数据一直变更,导致不稳定;
- 可能造成数据类型与实际类型不一致;
如何禁用动态映射,动态
mapping
的dynamic
字段进行配置,可选值及含义如下
- true:支持动态扩展,新增数据有新的字段属性时,自动添加对于的mapping,数据写入成功
- false:不支持动态扩展,新增数据有新的字段属性时,直接忽略,数据写入成功
- strict:不支持动态扩展,新增数据有新的字段时,报错,数据写入失败
主动创建(显示映射)
动态映射只能保证最基础的数据结构的映射
所以很多时候我们需要对字段除了数据结构定义更多的限制的时候,动态映射创建的内容很可能不符合我们的需求,所以可以使用PUT {index}/mapping
来更新指定索引的映射内容。
映射类型
我们要创建映射必须还要知道映射类型,否则就会走默认的映射类型,下面我们看看常用的映射类型
准备工作
我们先创建一个用于测试映射类型的索引
COPYPUT mapping_demo
字符串类型
字符串类型是我们最常用的类型之一,我们操作的时候字符串类型可以被设置为以下几种类型
text
当一个字段是要被全文搜索的,比如Email内容、产品描述,应该使用text类型,text类型会被分词
设置text类型以后,字段内容会被分词,在生成倒排索引以前,字符串会被分析器分成一个一个词项,text类型的字段不用于排序,很少用于聚合
keyword
keyword类型不会被分词,常用于关键字搜索,比如姓名、email地址、主机名、状态码和标签等
如果字段需要进行过滤(比如查姓名是张三发布的博客)、排序、聚合,keyword类型的字段只能通过精确值搜索到,常常被用来过滤、排序和聚合
两者区别
它们的区别在于
text
会对字段进行分词处理而keyword
则不会进行分词
也就是说如果字段是text
类型,存入的数据会先进行分词,然后将分完词的词组存入索引,而keyword
则不会进行分词,直接存储,这样划分数据更加节省内存。
使用案例
我们先创建一个映射,name是keyword类型,描述是text类型的
COPYPUT mapping_demo/_mapping{ "properties": { "name": { "type": "keyword" }, "city": { "type": "text", "analyzer": "ik_smart" } }}
插入数据
COPYPUT mapping_demo/_doc/1{ "name":"北京小区", "city":"北京市昌平区回龙观街道"}
对于keyword的name字段进行精确查询
COPYGET mapping_demo/_search{ "query": { "term": { "name": "北京小区" } }}
对于text的city进行模糊查询
COPYGET mapping_demo/_search{ "query": { "term": { "city": "北京市" } }}
数字类型
数字类型也是我们最常用的类型之一,下面我们看下数字类型的使用
类型 | 取值范围 |
---|---|
long | -263 ~ 263 |
integer | -231 ~ 231 |
short | -215 ~ 215 |
byte | -27 ~ 27 |
double | 64位的双精度 IEEE754 浮点类型 |
float | 32位的双精度 IEEE754 浮点类型 |
half_float | 16位的双精度 IEEE754 浮点类型 |
scaled_float | 缩放类型的浮点类型 |
注意事项
- 在满足需求的情况下,优先使用范围小的字段,字段长度越小,索引和搜索的效率越高。
日期类型
JSON表示日期
JSON没有表达日期的数据类型,所以在ES里面日期只能是下面其中之一
- 格式化的日期字符串,比如:
"2015-01-01"
or"2015/01/01 12:10:30"
- 用数字表示的从新纪元开始的毫秒数
- 用数字表示的从新纪元开始的秒数(epoch_second)
注意点:毫秒数的值是不能为负数的,如果时间在1970年以前,需要使用格式化的日期表达
ES如何处理日期
在ES的内部,时间会被转换为UTC时间(如果声明了时区)并使用从新纪元开始的毫秒数的
长整形数字类型的进行存储,在日期字段上的查询,内部将会转换为使用长整形的毫秒进行范围查询,根据与字段关联的日期格式,聚合和存储字段的结果将转换回字符串
注意点:日期最终都会作为字符串呈现,即使最开始初始化的时候是利用JSON文档的long声明的
默认日期格式
日期的格式可以被定制化的,如果没有声明日期的格式,它将会使用默认的格式:
COPY"strict_date_optional_time||epoch_millis"
这意味着它将会接收带时间戳的日期,它将遵守strict_date_optional_time限定的格式(yyyy-MM-dd"T"HH:mm:ss.SSSZ
或者 yyyy-MM-dd
)或者毫秒数
日期格式示例
COPYPUT mapping_demo/_mapping{ "properties": { "datetime": { "type": "date", "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis" } }}# 添加数据PUT mapping_demo/_doc/2{ "name":"河北区", "city":"河北省小区", "datetime":"2022-02-21 11:35:42"}
日期类型参数
下面表格里的参数可以用在date字段上面
参数 | 说明 |
---|---|
doc_values | 该字段是否按照列式存储在磁盘上以便于后续进行排序、聚合和脚本操作,可配置 true(默认)或 false |
format | 日期的格式 |
locale | 解析日期中时使用了本地语言表示月份时的名称和/或缩写,默认是 ROOT locale |
ignore_malformed | 如果设置为true,则奇怪的数字就会被忽略,如果是false(默认)奇怪的数字就会导致异常并且该文档将会被拒绝写入。需要注意的是,如果在脚本参数中使用则该属性不能被设置 |
index | 该字段是否能快速的被查询,默认是true。date类型的字段只有在doc_values设置为true时才能被查询,尽管很慢。 |
null_value | 替代null的值,默认是null |
on_script_error | 定义在脚本中如何处理抛出的异常,fail(默认)则整个文档会被拒绝索引,continue:继续索引 |
script | 如果该字段被设置,则字段的值将会使用该脚本产生,而不是直接从source里面读取。 |
store | true or false(默认)是否在 _source 之外在独立存储一份 |
布尔类型
boolean类型用于存储文档中的true/false
范围类型
顾名思义,范围类型字段中存储的内容就是一段范围,例如年龄30-55岁,日期在2020-12-28到2021-01-01之间等
类型范围
es中有六种范围类型:
- integer_range
- float_range
- long_range
- double_range
- date_range
- ip_range
使用实例
COPYPUT mapping_demo/_mapping{ "properties": { "age_range": { "type": "integer_range" } }}# 指定年龄范围,可以使用 gt、gte、lt、lte。PUT mapping_demo/_doc/3{ "name":"张三", "age_range":{ "gt":20, "lt":30 }}
分词器
什么是分词器
分词器的主要作用将用户输入的一段文本,按照一定逻辑,分析成多个词语的一种工具
顾名思义,文本分析就是把全文本转换成一系列单词(term/token)的过程,也叫分词,在 ES 中,Analysis 是通过分词器(Analyzer)来实现的,可使用 ES 内置的分析器或者按需定制化分析器。
举一个分词简单的例子:比如你输入 Mastering Elasticsearch
,会自动帮你分成两个单词,一个是 mastering
,另一个是 elasticsearch
,可以看出单词也被转化成了小写的。
分词器构成
分词器是专门处理分词的组件,分词器由以下三部分组成:
character filter
接收原字符流,通过添加、删除或者替换操作改变原字符流
例如:去除文本中的html标签,或者将罗马数字转换成阿拉伯数字等,一个字符过滤器可以有零个或者多个
tokenizer
简单的说就是将一整段文本拆分成一个个的词
例如拆分英文,通过空格能将句子拆分成一个个的词,但是对于中文来说,无法使用这种方式来实现,在一个分词器中,有且只有一个
tokenizeer
token filters
将切分的单词添加、删除或者改变
例如将所有英文单词小写,或者将英文中的停词a
删除等,在token filters
中,不允许将token(分出的词)
的position
或者offset
改变,同时,在一个分词器中,可以有零个或者多个token filters
。
分词顺序
同时 Analyzer 三个部分也是有顺序的,从图中可以看出,从上到下依次经过 Character Filters
,Tokenizer
以及 Token Filters
,这个顺序比较好理解,一个文本进来肯定要先对文本数据进行处理,再去分词,最后对分词的结果进行过滤。
测试分词
可以通过
_analyzer
API来测试分词的效果,我们使用下面的html过滤分词
COPYPOST _analyze{ "text":"hello world" # 输入的文本 "char_filter":["html_strip"], # 过滤html标签"tokenizer":"keyword", #原样输出}
什么时候分词
文本分词会发生在两个地方:
创建索引
:当索引文档字符类型为text
时,在建立索引时将会对该字段进行分词。搜索
:当对一个text
类型的字段进行全文检索时,会对用户输入的文本进行分词。
创建索引时指定分词器
如果设置手动设置了分词器,ES将按照下面顺序来确定使用哪个分词器
- 先判断字段是否有设置分词器,如果有,则使用字段属性上的分词器设置
- 如果设置了
analysis.analyzer.default
,则使用该设置的分词器 - 如果上面两个都未设置,则使用默认的
standard
分词器
字段指定分词器
为addr属性指定分词器,这里我们使用的是中文分词器
COPYPUT my_index{ "mappings": { "properties": { "info": { "type": "text", "analyzer": "ik_smart" } } }}
设置默认分词器
COPYPUT my_index{ "settings": { "analysis": { "analyzer": { "default":{ "type":"simple" } } } }}
搜索时指定分词器
在搜索时,通过下面参数依次检查搜索时使用的分词器,这样我们的搜索语句就会先分词,然后再来进行搜索
- 搜索时指定
analyzer
参数 - 创建mapping时指定字段的
search_analyzer
属性 - 创建索引时指定
setting
的analysis.analyzer.default_search
- 查看创建索引时字段指定的
analyzer
属性 - 如果上面几种都未设置,则使用默认的
standard
分词器。
指定analyzer
搜索时指定analyzer查询参数
COPYGET my_index/_search{ "query": { "match": { "message": { "query": "Quick foxes", "analyzer": "stop" } } }}
指定字段analyzer
COPYPUT my_index{ "mappings": { "properties": { "title":{ "type":"text", "analyzer": "whitespace", "search_analyzer": "simple" } } }}
指定默认default_seach
COPYPUT my_index{ "settings": { "analysis": { "analyzer": { "default":{ "type":"simple" }, "default_seach":{ "type":"whitespace" } } } }}
内置分词器
es在索引文档时,会通过各种类型
Analyzer
对text类型字段做分析
不同的 Analyzer
会有不同的分词结果,内置的分词器有以下几种,基本上内置的 Analyzer
包括 Language Analyzers
在内,对中文的分词都不够友好,中文分词需要安装其它 Analyzer
分析器 | 描述 | 分词对象 | 结果 |
---|---|---|---|
standard | 标准分析器是默认的分析器,如果没有指定,则使用该分析器。它提供了基于文法的标记化(基于 Unicode 文本分割算法,如 Unicode 标准附件 # 29所规定) ,并且对大多数语言都有效。 | The 2 QUICK Brown-Foxes jumped over the lazy dog’s bone. | [ the, 2, quick, brown, foxes, jumped, over, the, lazy, dog’s, bone ] |
simple | 简单分析器将文本分解为任何非字母字符的标记,如数字、空格、连字符和撇号、放弃非字母字符,并将大写字母更改为小写字母。 | The 2 QUICK Brown-Foxes jumped over the lazy dog’s bone. | [ the, quick, brown, foxes, jumped, over, the, lazy, dog, s, bone ] |
whitespace | 空格分析器在遇到空白字符时将文本分解为术语 | The 2 QUICK Brown-Foxes jumped over the lazy dog’s bone. | [ The, 2, QUICK, Brown-Foxes, jumped, over, the, lazy, dog’s, bone. ] |
stop | 停止分析器与简单分析器相同,但增加了删除停止字的支持。默认使用的是 _english_ 停止词。 | The 2 QUICK Brown-Foxes jumped over the lazy dog’s bone. | [ quick, brown, foxes, jumped, over, lazy, dog, s, bone ] |
keyword | 不分词,把整个字段当做一个整体返回 | The 2 QUICK Brown-Foxes jumped over the lazy dog’s bone. | [The 2 QUICK Brown-Foxes jumped over the lazy dog’s bone.] |
pattern | 模式分析器使用正则表达式将文本拆分为术语。正则表达式应该匹配令牌分隔符,而不是令牌本身。正则表达式默认为 w+ (或所有非单词字符)。 | The 2 QUICK Brown-Foxes jumped over the lazy dog’s bone. | [ the, 2, quick, brown, foxes, jumped, over, the, lazy, dog, s, bone ] |
多种西语系 arabic, armenian, basque, bengali, brazilian, bulgarian, catalan, cjk, czech, danish, dutch, english等等 | 一组旨在分析特定语言文本的分析程序。 |
IK中文分词器
IKAnalyzer
IKAnalyzer是一个开源的,基于java的语言开发的轻量级的中文分词工具包
从2006年12月推出1.0版开始,IKAnalyzer已经推出了3个大版本,在 2012 版本中,IK 实现了简单的分词歧义排除算法,标志着 IK 分词器从单纯的词典分词向模拟语义分词衍化
中文分词器算法
中文分词器最简单的是ik分词器,还有jieba分词,哈工大分词器等
分词器 | 描述 | 分词对象 | 结果 |
---|---|---|---|
ik_smart | ik分词器中的简单分词器,支持自定义字典,远程字典 | 学如逆水行舟,不进则退 | [学如逆水行舟,不进则退] |
ik_max_word | ik_分词器的全量分词器,支持自定义字典,远程字典 | 学如逆水行舟,不进则退 | [学如逆水行舟,学如逆水,逆水行舟,逆水,行舟,不进则退,不进,则,退] |
ik_smart
原始内容
COPY传智教育的教学质量是杠杠的
测试分词
COPYGET _analyze{ "analyzer": "ik_smart", "text": "传智教育的教学质量是杠杠的"}
ik_max_word
原始内容
COPY传智教育的教学质量是杠杠的
测试分词
COPYGET _analyze{ "analyzer": "ik_max_word", "text": "传智教育的教学质量是杠杠的"}
本文由
传智教育博学谷狂野架构师
教研团队发布。如果本文对您有帮助,欢迎
关注
和点赞
;如果您有任何建议也可留言评论
或私信
,您的支持是我坚持创作的动力。转载请注明出处!
关键词:
-
Linux系统上创建.NET6项目(通过命令行(CTL)方式)
前言平时大家创建项目基本上都是借助开发工具创建,比如visualstudio,visualstudiocode,今天我们在Linux
来源: 6000+字讲透ElasticSearch 索引设计
Linux系统上创建.NET6项目(通过命令行(CTL)方式)
15日起内地赴港澳签注办理更便捷 端午赴港澳机票较五一降三成|环球视点
索尼最强旗舰!Xperia 1 V发布:8999元起
4月SUV销量排名:比亚迪双星无敌!燃油车苦苦挣扎
当前视点!Linux重启Java的.sh脚本shell
stm32 boot0硬件接法导致的概率性启动失败问题总结和反思
k3s 证书过期修改
《种地吧》下期精彩:后陡门篮球赛主打团结 种地团直面成长阵痛-当前资讯
孟羽童视频回应离职格力:下一步将申请读研|环球观点
2999元!佳能发布掌上Vlog机PowerShot V10 比手机还小巧
焦点热讯:索尼放大招 Xperia 1 V用上双层晶体管传感器:画质媲美全画幅相机
天玑9200+正式发布!解决旗舰用户三大痛点 带来顶级游戏性能体验 世界新消息
黑寡妇毒杀亲夫
【天天热闻】手动挡正确停止和关闭发动机 以及关闭发动机钥匙的步骤
动力节点老杜B站Spring6学习笔记—Spring的入门程序
IOC类图
【独家】泰州姜堰:绿色能源清风吹拂一座城
环球新消息丨借鉴新加坡经验 深圳地铁拟推行早起上班优惠价:缓解早高峰拥挤
正式超越日本!一季度中国成全球第一大汽车出口国 天天速看料
三层防护 稳健医用外科口罩便宜了:3盒150只到手21.8元
全球快播:年内最大降幅?国内油价或即将大幅度下调 就在5月16日
微信开启“带货时代”:公众号今日起也能带货了
华硕笔记本A45v怎么清空所有数据?华硕笔记本a45v参数配置
电脑网页变成灰色是怎么回事?电脑网页变成灰色怎么解决?
国家移民管理局发布公告 5月15日起全面恢复口岸快捷通关|焦点消息
金立V183什么时候上市的?金立V183手机参数
宏基笔记本白屏是什么原因?宏基笔记本白屏怎么解决?
qq邮箱怎么点亮图标?qq邮箱格式怎么写?
周迅身高是多少?周迅个人资料简介
打电话不显示号码是怎么回事?打电话不显示号码怎么办?
盛夏晚晴天吻戏在哪几集?盛夏晚晴天电视剧结局是什么?
版权符号怎么打出来?版权符号html代码
吉林市为什么和省一个名字?吉林市旅游必去十大景点
世界快看:第二章、操作系统基本原理
世界最资讯丨蒙哥马利算法
每日观点:热烈欢迎成都市武侯区人社局领导莅临璞华考察参观
山西印发冬小麦后期田间管理意见
世界关注:荣盛发展年报遭问询,被追问营收大幅下滑、业绩大额亏损且亏损面进一步扩大原因及合理性
全球最大超算竞赛 现场DIY设计并攒机 北大学生拿下总冠军
美国4S店躺赢 巴菲特不爱车企爱经销商 天天速看
华为海外连开两场重磅发布会:发力全球市场势头不减! |每日视讯
太贵卖不动?NV又准备RTX 4070公版:4799元国内玩家抢吧 全球聚看点
人造肉更环保?新研究表明:对气候影响可能是普通牛肉25倍|看点
焦点快报!2023年上海市全民数字素养与技能提升月启动
Docker网络类型
Java之图片上传与删除功能的实现
用户分享 | Dockquery,一个国产数据库客户端的初体验
Django SQL注入漏洞分析(CVE-2022-28346) 全球报资讯
openAI发布v0.2.0了 全球快讯
环球热资讯!奥迪“全新”A6曝光!车尾神似5系,换保时捷引擎高级吗?
【全球新要闻】孟羽童曾称董明珠不可复制:没有人可以成为第二个董明珠
男子机场拍到李若彤被妻子怀疑出轨 李若彤发帖为其澄清 重点聚焦
2599元 尼康首款Z卡口电动变焦镜头来了:广角、特写都能拿捏
长沙一停车场要求按颜色停放 违停罚100元 律师:没法律效力
热点评!大手笔!丰田承认开发电动车失败 决定再砸500亿元
观天下!Haynes:有位湖人球员说 让勇士叽叽歪歪继续抱怨吧
深交所向*ST海投发出问询函|世界实时
环球新消息丨Android 14发布:首批适配机型公布
【环球热闻】谷歌首款平板Pixel Tablet发布:自研G2处理器、边框感人
环球观点:董明珠“接班人”孟羽童离职:曾称工作21个小时 工作强度太大
“蔚小理”变成“理哪零”造车新势力淘汰赛加速
今年来新增专项债已发行逾1.6万亿元
【财经分析】英国制造业增长乏力 与服务业分化明显
出行信息早知道!河北最新天气预报、限行提示、高速路况请查收→
全球简讯:MIUI 14开发者预览版上线:小米13、小米平板6等喜提安卓14
取代OLED!未来iPhone屏幕脱胎换骨:要用MicroLED屏-环球讯息
史上最坚固铰链!谷歌Pixel Fold折叠屏手机发布:处理器独一无二
谷歌Pixel 7a发布:3500元 不标配充电器
世界视讯!学系统集成项目管理工程师(中项)系列20_变更管理
bothhand ns0013lf_bothhand
世界看点:阿里云打5折降价 百度回应:这是感受到了竞争威胁
世界动态:彻底搞懂 Cookie、Session、Token、JWT
在 IDEA 中创建 Java Web 项目的方式(详细步骤教程)|天天聚看点
环球热讯:实验五
观点 | 美国通胀十连降后还需担心吗?
反转!高铁掌掴事件完整视频曝光:双方11秒打3巴掌、王某脏话不断
理想汽车:没有降价的打算 上市定价就是最有竞争力区间 天天简讯
全球微动态丨6月9日上映!《变形金刚7》IMAX海报发布:汽车人、猛兽侠集结
【全球快播报】DDR5内存大跌!24GB高频内存仅399元
俄罗斯质疑美国登月造假:50年前能做到 为何现在反而做不到 每日信息
锻造1-450最省材料攻略_锻造多少会碎-世界热门
动态焦点:去年全球钴产量达19.8万吨 电动汽车消耗7.4万吨
grand theft auto vc 8.1怎么解决_grand theft auto vc 8 1
Java for循环标签跳转到指定位置 全球快报
食品添加剂都是“洪水猛兽”?科技与狠活你知道多少? 今日观点
每日速讯:网友曝光南京江边惊现扬子鳄:我国特有种 一级保护动物
超越1英寸大底!华为P60 Pro凭什么能拿到DXO拍照世界第一 当前看点
Z9良心缩水 尼康发布全画幅微单数码相机Z8:售价27999_焦点要闻
美术315 环球快报
大众软件部门两年亏损250亿 管理层集体被炒 环球观速讯
世界最强货运飞船之一 “太空快递小哥”天舟六号发射升空|环球新要闻
重返斯莱特林!马尔福少爷畅玩《霍格沃茨之遗》-头条焦点
FFT(快速傅里叶变换)
ASP.NET Core MVC 从入门到精通之文件上传 世界快资讯
债市日报:5月10日_世界观焦点
美国债务上限谈判无进展 拜登可能取消G7行程 热文
悦达起亚大地震!管理层轮休1年 公司资不抵债|世界实时
MAXHUB双发x86兆芯、Arm飞腾国产CPU电脑!国产化近95%
单卡30秒跑出虚拟3D仙女老婆!毛孔细节清晰