elasticsearch

elasticsearch是一个高性能高扩展性的索引系统,底层基于apache lucene。

可结合kibana工具进行可视化。

概念:

  • index 索引: 类似SQL中的一张表,索引名必须是全小写单词。
  • type(索引类型):设计初衷是用type对相同逻辑结构(字段名)数据的归并,一个index中只能有一种 type,在6.0版本之后被标记为过时(deprecated),在后续大版本(7.x, 8.x+)中会将被完全弃用。
  • document 文档:若干个键值对的数据,类似SQL的一行记录。

检索

ES的CRUD可通过kibana工具包中的Dev Tools进行。

使用http请求实现索引查询,search操作请求基本格式为GET /<index-name>/_search

一个简单查询,无条件查文档的请求如下:

GET /myindex/_search
{"query": {"match_all": {}}
}

一个简单查询(如无条件查文档)返回的形式如下:

{"took" : 0,"timed_out" : false,"_shards" : {"total" : 5,"successful" : 5,"skipped" : 0,"failed" : 0},"hits" : {"total" : 1,"max_score" : 1.0,"hits" : [{"_index" : "myindex","_type" : "_doc","_id" : "-31ddGgBVZ-2SafgL7-y","_score" : 1.0,"_source" : {"name" : "Jack Ma3"}}]}
}

其中字段意义如下:

  • took 查询耗时
  • time_out 查询是否超时
  • _shards 查询在分片上执行的结果状态
  • hits 查询结果
  • hits.total 匹配的总文档数
  • hits.max_score 结果文档的最高分值
  • hits.hits 匹配上的文档结果集合
  • hits.hits._index 该文档所在索引
  • hits.hits._type 该文档所在类型
  • hits.hits._id 文档id
  • hits.hits._score 该文档与查询条件的匹配分值
  • hits.hits._source 文档字段键值数据

查询请求一般格式首先是GET的HTTP方法,请求地址形式为“//_search”,http请求携带的数据为一个json,包括"query"部分,该部分是查询条件限定文档条数通过指定"size"实现。在分页场景中设置查询起始位置通过指定"from"实现。可通过设置"sort"指定排序条件。如:

GET /myindex/_search
{"query": {"match_all":{}},"from": 100,"size": 10,"sort":"age"
}

查询条件部分,"query",其内容为一个json对象,键是布尔值谓词或筛选谓词(filter),值是对应内容,一般是json对象。布尔值谓词包括布尔逻辑操作谓词、文档匹配谓词,前者对应布尔逻辑的与或非等,后者用于判断一个文档是否满足某种要求。

谓词是查询条件json对象的键,其值一般是json对象(或者对象数组),值内容json对象的键是谓词,从json对象顶层深入往里看,查询条件类似前缀表达式,首先看到的是谓词(operator),然后才看到谓词对应的操作数(operand)。
例:

#下列内容中“#”后内容表示注释,尽管json中没有注释的概念
{"query": {"bool": {       #query下允许bool,表示一个bool条件,内容是json对象,键名是谓词,多个键是"and"关系"must": [       #must表达必须包含给定的若干个条件,类似“与 and”{"match": {  #表示下面的json对象表达一个文档字段匹配条件"age": 50   #表示字段“age”值为50的文档}},{"match": {"gender": "male"}}],"must_not": {   #must_not必须不匹配,可是多个条件(数组)"match": {"name": "Jack Ma"}}}}
}

有以下查询谓词:

  • match_all 无条件匹配所有文档。
  • match_none 不匹配任何文档
  • match 值内容是json对象,键是文档字段,值是目标匹配值或者带选项的值(json对象,目标值在"value"字段)。该种查询将会对字段值进行分析。
  • ids 根据若干id查询文档。
  • prefix 非分析性查询。查询字段的项是否具有给定前缀。
  • match_phrase
  • match_phrase_prefix
  • term 非分析性查询。精确匹配一个项
  • terms 类似term,匹配给定数组中任意一个值
  • terms_set
  • wilcard 非分析性查询。支持通配符*?的查询。查询将遍历每个项,故应避免通配符打头的查询。
  • regexp 正则匹配。是在字段的项(terms)上的匹配,而非原文本。
  • fuzzy 根据给定值对字段的项进行模糊查询,以编辑距离度量模糊性。
  • bool 表明是一个布尔条件,其下是若干谓词组成的复杂条件
  • must 必须匹配,一般对多个条件使用(数组),类似“与 AND”
  • must_not 不匹配,相当于"非 NOT",可以对多个条件(数组)使用
  • should 语义为“应该”匹配,“逻辑或 OR”与之接近(可指定子条件的至少匹配个数),一般对若干条件使用(或),表示匹配多个条件中的若干个条件,一般指至少匹配1个,通过与should平行层级的键minimum_should_match指定should中需要至少匹配的条件数量。在某些情况默认至少匹配1个。

谓词值是json对象时,其多个键名(子谓词)之间的关系基本是“与 and”关系。与"should"(平行层级)共存时,需小心"should"能匹配的条件数以及条件至少匹配数"TODO"的设置。

termterm用于精确匹配倒排索引中的一个项(term)。也可用在范围类型数据(range data types)上。

GET _search
{"query":{"term": {"field1": "value1"}}
}GET _search
{"query": {"bool": {"should": [{"term": {"field1": {"value": "value1","boost": 2.0        #相比boost:1.0的条件重要两倍}}},{"term": {"field2": "value2"}}]}}
}

如,字段“content”的类型配置为text,现有一文档,其该字段的值为“hello es”,在入库该文档时,由于字段类型是text,分词器会将其分为"hello"和"es"两个项(term)存入倒排索引。在用term查询时,如果查询字段"content"上的值"hello"是能检索到该文档的(或查询值为"es"也可检索到),但利用term查询字段"content"上值为"hello es"的文档,则不能命中上述文档,因为在倒排索引中没有"hello es"的项。

terms_set: terms_set

GET _search
{"query":{"terms_set": {"terms": ["value1","value2",...],"minimum_should_match_field":"<another_field>"  #引用文档其他整型字段的值来指定terms中需要匹配的term的个数"minimum_should_match_script": "或者通过脚本提供需匹配个数"}}
}

matchmatch会用分析器进行分词。

GET /_search{"query": {"match": {"my_field":"my_value"}}
}

前缀匹配prefixmatch_phrase_prefix

GET _search
{"query":{"prefix": {"FIELD": "PREFIX"}}
}

模糊查询fuzzy 在字段的项(term)上匹配

GET _search
{"query":{"fuzzy":{"field1": {"value": "my_value","fuzziness": 4      #编辑距离参数以配置模糊程度}}}
}

根据id查询多个文档:利用_mget,索引名和类型是可选项。 GET /_mget GET /<index>/_mgetGET /<index>/_doc/_mget

GET /mget
{"ids":["id1", "id2"]
}

批获取 multi-get
根据多个条件一次性获取

GET /_mget      #或 /<index>/_mget  或 /<index>/_doc/_mget
{"docs": [{"_index": "myindex"  #如果URL中没有<index>则必须提供;如果URL中有<index>,可不提供"_index",若提供则覆盖URL中<index>作为查询索引"_type": ""     #URL中没有<type>都不要求提供"_id": ""       #需提供,以匹配文档}]
}

批量操作 Bulk API
REST API服务端点是_bulk,请求携带数据是以行分隔的json(NDJSON),即一行一json,基本形式如下:

action_and_meta_data\n
optional_source\n
action_and_meta_data\n
optional_source\n
....
action_and_meta_data\n
optional_source\n

携带行分隔json数据的请求,其http头“content-type”的值需设置为"application/x-ndjson"。

Bulk API允许的操作有“index”、“create”、“delete”、“”、“update”。

POST /_bulk
{"index": {"_index": "myindex","_type":"", "_id": ""}}   # index operation
{"field1":"val1"}  # data carried by index operation
{"create": {"_index":""}
{"field1":"val1"}
{"update": {"_index":"","_type":"","_id":""}}
{"doc": {field1":"val1"}}  #注意:update需指定是doc还是script方式,而不是直接提供文档结构数据
{"delete":{"_index":"", "_id":""}}  #delete不携带数据体

批查询_msearch

计数_count

GET /.../_count     # /_count  /<index>/_count
{"query": ...
}

复制索引 reindex:将一个索引中的若干文档复制到另一个中,rest服务端点_reindex

POST _reindex
{"source":{"index": "myindex"  #必须。指定源索引,单个或多个(数组)"_source": ...      #可选。指定复制的字段,默认全部字段。"type": ""          #可选。单个或多个(多个时对应多个索引情况)"sort": ...     #排序标准,当指定size时有意义。"query": ...    #可选。筛选条件"size": ...     #scroll batch size},"dest": {"index": ""     #必须。指定目标索引"op_type": "create"   #可选参数,复制操作类型"version_type": ""  #可选参数,指定版本类型}"size": <number>    #可选。指定复制文档数量,默认全部。"script": ...       #可选。脚本
}

立即更新 ?refresh: index,update,delete等操作的影响默认在一段时候后才会被其他(查询)操作观察到,而操作是立即返回的。即类似于多线程,一个线程对数据的更新在一定延迟后才对其他线程可见。这一行为可通过?refresh参数控制,为false时(默认情况),操作影响在一定延迟后可见;为true或空时,立即对其他(查询)操作可见,当然,这需要考虑因此可能引发的性能问题;为wait_for时,等待索引的自动刷新操作时更新数据,索引刷新动作根据index.refresh_interval(默认1秒)周期性更新。

分页
指定from(默认从0开始), size(默认10条?), sort(默认升序):

GET /myindex/_search
{"query": {"match_all":{}},"from": 100,"size": 10,"sort":"created_time"
}

排序

  • 单字段排序,以默认升降序:sort: "字段名"
  • 单字段排序,指定升降序
{"sort": {"字段名": {#desc降序,asc升序"order": "desc" 或 "asc"}
}
  • 多字段排序,以默认升降序:`sort: ["字段1", "字段2"]
  • 多字段排序,每个字段指定升降序。

sort的各种形式:

{"sort" : [{ "date" : {"order" : "asc"}},"user",{ "name" : "desc" },{ "age" : "desc" },"_score"]
}

指定最小分值 min_score :

GET /_search
{"min_score": 0.8,"query": ...
}

支持多索引检索(multi index),请求地址中索引部分由多个索引以逗号拼接而成,_all表示所有索引。多索引查询中索引名支持通配符*,如所有以"myindex"打头的索引:myindex*,以及通配符+排除-,如以"myindex"打头但除了myindex1:myindex*,-myindex1

多索引相关参数:

  • ignore_unavailable true或false,忽略不存在或已关闭(closed)的索引
  • allow_no_indices false或true,表示在通配符未能匹配任何索引时是否需要报异常。
  • expand_wildcards 为其中之一none,open,closed,all, open,closed(等同all)。分别指禁用通配符扩展、仅扩展到open的索引、仅扩展到closed的、扩展到两种的。

时间日期相关参数……。

通用参数

  • pretty 改观返回数据的可视化
  • ……

可指定需要返回的字段:

GET /myindex/_search
{"query":{"match_all":{}},"_source":["field1","field2"]
}
GET ...
{..."_source": {"include": ["profile"],"exclude": ["profile.location"]}
}

单个字段:_source: "字段名";多个字段: _source:["字段1","字段2"];不返回: _source:false
_source_include, _source_exclude

不想返回hits数组(如在聚合查询时):设置size为0:

GET ...
{"query": ...,"size": 0,"aggs": ...
}

{"doc_fields":["field1"] }返回'not_analyzed'的字段,'text'之类的字段不允许在doc_fields中。

查询谓词可以用在"query"和"filter"两种上下文,"query"要解决的问题是“是否匹配+匹配得怎么样(即相似性、分值)”,"filter"解决的是“是否匹配”,filter更多用于结构性、可直接匹配性的字段(数值、枚举值字段)。

游标式读取
ES支持以“游标”方式读取大批量文档,文档查询时设置以“游标”方式返回数据,ES每批次返回一定数量的文档,以及一个字符串指针,以供下次继续查询使用。

游标式读取报错:游标上下文失效?TODO

TODO _index和_type,有例子为:_index: test_20190102, _type: test_t (_t应该是配置的后缀,_index和_type有相同的前缀,_index名带了日期)

增删改

创建/替换文档: POST /<index-name>/_doc/ 或指定文档id: PUT /<index-name>/_doc/<id>,PUT时意指创建或者替换,必须指定文档id。POST时意指创建或更新,可不指定文档id。索引不存在时会自动创建索引。其中的_doc指type,index有且仅有一个type,默认为_doc。PUT /<index>/_doc/<id>/_create,仅作插入(创建),如果文档已存在,则报失败。

# create a document
POST /myindex/_doc
{"name":"Jack Ma"
}# create or replace a document
PUT /myindex/_doc/<id>
{"name":"Jack Ma"
}

更新文档: POST /<index-name>/_doc/<id>/_update
更新id为“1”的文档的"name"字段,并添加一个“age”和"films"字段。更新可通过文档内容或脚本完成,分别提供顶级键“doc”或“script”指定。更新请求的地址中如果没有最后的"_update",则是创建或替换(创建/替换没有顶级键"doc"或"script",而是直接提供文档内容)。

POST /myindex/_doc/1/_update
{"doc": {"name":"Stephen Chow","age":50,"films": ["喜剧之王","九品芝麻官"]}
}

也可以通过脚本更新文档。
将"age"字段值加6:

POST /myindex/_doc/1/_update
{"script:"ctx._source.age += 5"
}

删除文档:通过id删除 DELETE /<index-name>/_doc/<id>

DELETE /myindex/_doc/`

通过查询删除:DELETE /<index>/_delete_by_query

DELETE /myindex/_delete_by_query
{"query": {...}
}

通过查询条件更新:POST /<index>/_update_by_query

聚合 aggregation

GET ...
{..."aggs": ...  #聚合
}

均值 avgavg

{"aggs": {"my_return_field": {    #聚合结果字段名"avg": {"field": "my_field" "missing": value-for-missing-such-field     #可选。在字段缺失时的补充值}}}
}
{"aggs": {"my_avg": {"avg": {"script": "doc.my_field.value" }}}
}

加权均值weighted_avg,计算公式∑(value * weight) / ∑(weight)

{"aggs": {"my_return_field": {"weighted_avg": {"weight": {"field": "权值字段","missing": ...  #可选。默认忽略该文档},"value": {"field": "值字段","missing": ...      #可选。默认权值为1}}}}
}

数组数据+单值权重:对于一个文档的字段值为数组权重值为单值的情况,视为各自元素是相互独立的,即各自元素乘以权重,权重和(分母)是参与计算的权重的和,即元素多少个则该次计算就有多少倍权重参与计算。

#数据为:
{"g": [5,2,8],"w": 3
}
#聚合查询为:
{"aggs": {"weighted_avg": {value: {"field": "g"},"weight": {"field": "w"}}}
}
#结果为: (5*3+2*3+8*3)/(3+3+3)

最大值 max

最小值min

sum

百分位percentiles 要求数据字段类型为数值型。

{"aggs":{"my_return_field":{"percentiles": {"field": "数据字段","percents": [,,,] #可选。百分位点,默认[ 1, 5, 25, 50, 75, 95, 99 ]}}}
}
#返回
{"aggregations": {"my_return_field": {"values": [{"key": 1.0, #百分位点"value": xxx    #数据点},{ "key": 99.0, "value": xxx }]}}
}
}

cardinalitycardinality ……

常用统计量stats 返回 和(sum)、个数(count)、最小值(min)、最大值(max)、均值(avg)。

{"aggs": {"my_return_field": {"stats": {"field": "统计字段",    #或通过脚本"missing": xxx      #可选。}}}
}
#返回
{"aggregations": {"my_return_field": {"count": 4,"min": 20.0,"max": 80.0,"avg": 55.0,"sum": 220.0}}
}

常见统计量extended_stats 返回 和(sum)、平方和(sum_of_squares)、个数(count)、最小值(min)、最大值(max)、均值(avg)、方差(variance)、标准差(std_deviation)等统计量。

{"aggs": {"extended_stats": {"field": "统计字段"  #字段或者脚本'script'}}
}

值计数terms 返回值以及对应计数

{"aggs":{"my_facet":{"terms"{"field": "统计字段" #在字段(field)上或使用脚本(将"field"换为"script": ...)"size": <结果条数(默认以计数降序排列)>}}}
}

返回样例

{..."aggregations": {"my_facet": {...buckets:[{"key": "词1","doc_count": <n1>  #对应计数,默认按计数降序排列},{"key": "词2","doc_count": <n2>}]}}
}

经纬坐标边界查询:返回匹配文档的经纬坐标所覆盖的边界,以边界左上和右下两点坐标为代表数据返回,要求数据字段类型为geo_point

{"aggs":{"my_return_field":{"geo_bounds":{"field": "geo-data-field"}}}
}

经纬坐标中心点查询geo_centroid

自定义map-reduce脚本聚合scripted_metric

{"aggs":{"my_return_field":{"scripted_metric": {"init_script": ...,"map_script": ...,"combine_script":...,"reduce_script":...}}}
}

……

索引CURD

列举索引:GET /_cat/indices?vGET /_cat/indices列举所有索引及相关信息,一索引一行,各列表示相关信息,第三列是索引名,?v参数表示需要显示表头。

创建索引PUT /<索引名>,索引名必须全小,可以提供索引的字段配置。

PUT /myindex
{"mappings": {"_doc": {"properties": {"field1": {"type": "keyword"},"field2": {"type": "text" },"field3": {"type": "integer" },"field4": {"type": "date" }}}}
}

字符串形态的类型有两种,textkeyword,text类型的字符串将会被分析器分词,分词后一个词叫做一个'term',然后存入倒排索引。keyword类型字符串不会被分词。

删除索引DELETE /<索引名>,删除索引将导致其中所有文档被删除。

显示集群状态
GET /

脚本

TODO
查询里脚本的可用上下文变量

安装 配置 运行

安装elasticsearch

进入es下载页面,选择下载最新稳定版包,以6.5.4为例,下载地址 https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.5.4.tar.gz 。
解压程序包并启动单节点集群:

tar -xzvf elasticsearch-6.5.4.tar.gz
cd  elasticsearch-6.5.4
bin/elsaticsearch
# bin/elasticsearch -d #(daemonize)后台运行
#后台执行ES,将pid输出到FILE
# bin/elasticsearch -d -p FILE
#通过启动命令行参数覆盖配置文件中的配置  -E参数
# bin/elasticsearch -E<key>=<value>#关停ES程序
kill -SIGTERM <pid>

ES默认在9200端口提供REST API服务。ES也提供transport api服务,该服务区别于REST API的地方主要是其数据交互是以java对象序列化/反序列化进行,该形式的API正计划被弃用。

如果报错max virtual memory areas vm.max_map_count [xxxx] is too low,可在/etc/sysctl.conf中添加vm.max_map_count=655360,然后sysctl -p来调整相应系统参数,之后可成功启动es。

配置 elasticsearch

环境变量ES_PATH_CONF指定ES配置文件存放目录。

配置目录可有如下配置文件:

  • elasticsearch.yml
  • jvm.options JVM参数,一行一个参数。支持仅对特定jvm版本启用配置的语法。环境变量ES_JAVA_OPTS配置jvm参数。
  • log4j2.properties 日志相关

默认配置文件目录$ES_HOME/conf/。

#elasticsearch.yml
action.auto_create_index: myindex*,other_inx*,+allowed_inx*,-disallowed_inx* #对满足模式的索引名按需自动创建索引,支持通配符,支持以逗号拼接出的多个模式,“+”开头的表示允许,“-”开头的表示禁止cluster.name: #集群名,默认“elasticsearch”,同集群名的节点形成集群node.name: #节点名path:data:  #索引数据存取目录,可以配成多个目录的数组logs:  #日志输出目录
network.host: #服务网口,特殊值_local_, _site_, _global_
#特殊的值:${prompt.text}和${prompt.secret}表示将在控制台提示并读取输入作为对应配置值
#node.name: ${prompt.text}discovery.zen.ping.unicast.hosts:  #若干<host>:<port>,<port>未指定时,将会扫描对应主机的9300~9305端口
discovery.zen.minimum_master_nodes: <数量>  ##multi-search, multi-get, bulk相关
rest.action.multi.allow_explicit_index: true(默认)|false  # false时,将会拒绝request-body中修改URL参数中指定的index的行为

环境变量ES_TMPDIR配置ES临时文件目录,linux版默认/tmp

安装kibana

进入kibana下载页面,选择下载最新稳定版,以6.5.4为例,下载地址 https://artifacts.elastic.co/downloads/kibana/kibana-6.5.4-linux-x86_64.tar.gz 。解压程序包并启动,程序将在默认的5601端口提供Web服务。

tar -xzvf kibana-6.5.4-linux-x86_64.tar.gz
cd kibana-6.5.4-linux-x86_64
bin/kibana

配置 kibana

conf/kibana.yml

server.host:  #kibana服务绑定的host, 0.0.0.0绑定到所有网络接口
server.port:

转载于:https://www.cnblogs.com/xmaples/p/10308992.html

elasticsearch——海量文档高性能索引系统相关推荐

  1. ElasticSearch入门系列(三)文档,索引,搜索和聚合

    一.文档 在实际使用中的对象往往拥有复杂的数据结构 Elasticsearch是面向文档的,这意味着他可以存储整个对象或文档,然而他不仅仅是存储,还会索引每个文档的内容使之可以被搜索,在Elastic ...

  2. ElasticSearch学习文档

    ElasticSearch 第一节 ElasticSearch概述 1.1ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTfulw ...

  3. 关于ElasticSearch新建文档的姿势

    定义如下mapping,并且创建索引,索引包括四个字段 有三个分片 (number_of_shards),每个分片有一个副本分片(number_of_replicas) PUT books {&quo ...

  4. elasticsearch 路由文档到分片

    路由文档到分片 当你索引一个文档,它被存储在单独一个主分片上.Elasticsearch是如何知道文档属于哪个分片的呢?当你创建一个新文档,它是如何知道是应该存储在分片1还是分片2上的呢? 进程不能是 ...

  5. ElasticSearch创建文档

    ElasticSearch创建文档 创建文档有两种途径 直接在XcontentBuilder构建json数据,创建文档. // 描述json 数据/** {id:xxx, title:xxx, con ...

  6. 【elasticsearch】文档 CRUD 增删改查 以及 相关 参数

    1.概述 转载:https://mp.weixin.qq.com/s/aOZnZpAC4c_dYkVW8DfNPg 在Elasticsearch中,文档(document)是所有可搜索数据的最小单位. ...

  7. 打破技术壁垒, 用SpreadJS 抢占“表格文档协同编辑系统”的入市先机

    本文由葡萄城技术团队于CSDN原创并首发 转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 在线文档的发展机遇与挑战 现阶段,复工复产成为企业的迫切诉求.线上 ...

  8. ElasticSearch:文档字段类型及存储

    文章目录 1.文档字段存储 2.字段类型 2.1.字段的核心类型 2.2.衍生及多值类型 1.文档字段存储 文档字段指的是一个文档中存储的单元,比如以下文档中的username.age.favor就是 ...

  9. Redis集群部署文档(Ubuntu15.10系统)

    Redis集群部署文档(Ubuntu15.10系统) (要让集群正常工作至少需要3个主节点,在这里我们要创建6个redis节点,其中三个为主节点,三个为从节点,对应的redis节点的ip和端口对应关系 ...

最新文章

  1. java doc转pdf_java 完美解决 ppt/pptx 转pdf 源码
  2. 系统、应用监控的缜密思路,堪称性能瓶颈的克星
  3. tkinter如何lable重复显示到同一行中_如何创建包含 CAD 导入和选择的仿真 App
  4. Redis 响应延迟问题排查
  5. 计算机科学导论第12版答案,计算机科学导论第12章参考答案.pdf
  6. grasshopper python_【转】精华教学 | GH_Cpython——将原生的 Python 与机器学习框架引入Grasshopper...
  7. w3school离线手册
  8. 计算机锁屏图片怎么设置方法,电脑锁屏照片怎么设置
  9. 请结合实例说明欧洲中世纪哥特式建筑的风格特点
  10. Excel:批量将某字符替换为“换行符”
  11. itextpdf对PDF文件进行签名
  12. oeasy教您玩转 linux 010213 中文 fcitx
  13. 联想微型计算机开机密码忘记了,lenovo台式电脑忘了开机密码简单解决的方法,小孩子就能搞定的...
  14. HDLC广域网协议设置
  15. 自从有了BI商业智能系统,再也不用担心我的作图了!!!(图文)
  16. Supporting Online Material for Lab Experiments for the Study of Social-Ecological Systems
  17. “四大发明”活字印刷当排首位!
  18. oracle用户sysman过期,sysman密码过期导致oem无法使用
  19. 目前互联网最详细的5G注册流程
  20. 精准医学 | 十篇文章读懂DNA甲基化与疾病(肿瘤)的关系

热门文章

  1. 管理角色认知-新晋管理常常犯的错
  2. 【洛谷 1879】玉米田
  3. .net core mvc初级教程(六)
  4. 常见的几种异常类型-熟记
  5. Spring Security原理与应用
  6. shell中的常用通配符,字符类
  7. 1003 阶乘后面0的数量
  8. Ubuntu各大分支版本功能介绍及下载地址
  9. Ph.D Grind 阅读感想 By 张雄
  10. matlab imhist灰度直方图