Search

搜索条件可以通过查询字符串,也可以在请求体中传递。

搜索接口支持从多个索引中查找文档vj。

基本格式:

# 单索引内检索文档
GET /{index}/_search?q={field}:xxx# 多索引内检索文档
GET /{index1, index2}/_search?q={field}: xxx# 全部索引内检索文档
GET /_all_/_search?q={field}: xxx

URI Search

通过URI传参的方式比较简单,但是不能支持所有的搜索选项。

RUI支持传参如下:
https://www.elastic.co/guide/en/elasticsearch/reference/7.2/search-uri-request.html

Request Body Search

搜索请求可以使用search DSL,并包含Query DSL,比如:

GET /twitter/_search
{"query": {"term": {"user": "kimchy"}}
}

注意:其实GET请求也是可以带请求体的。考虑到不是所有的客户端支持GET携带请求体,因此,也上请求也可以通过POST发送。

返回结果如下:

{"took" : 5,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 2,"relation" : "eq"},"max_score" : 0.47000363,"hits" : [{"_index" : "twitter","_type" : "_doc","_id" : "A6y0umsBAkV3IICsYCLL","_score" : 0.47000363,"_source" : {"user" : "kimchy","post_date" : "2009-11-15T14:12:12","message" : "trying out Elasticsearch"}},{"_index" : "twitter","_type" : "_doc","_id" : "BKzNumsBAkV3IICsUCJn","_score" : 0.47000363,"_routing" : "kimchy","_source" : {"user" : "kimchy","post_date" : "2009-11-15T14:12:12","message" : "trying out Elasticsearch"}}]}
}

如果只是想知道是否有匹配条件的文档,可以设置size参数为0,这表示你并不需要搜索的结果。或者,将terminate_after设置为1,表示只要找到一个一个文档,查询操作就可以结束了。

curl -X GET "localhost:9200/_search?q=message:number&size=0&terminate_after=1"

如果查询时不指定任何条件,将返回所有结果,比如:

GET /twitter/_search

查询的方式:

  • match 查询,针对全文检索
  • term 查询,词条精确搜索

查询的逻辑运算:

搜索时如果有多个关键字,ES默认他们是的关系:

GET twitter/_search
{"query": {"match": {"message": "out me"}}
}

以上搜索查找message字段中包含outme的文档。

如果要指定and搜索,需要使用布尔查询:

GET twitter/_search
{"query": {"bool":{"must": [{"match": {"field1": "out"}},{"match": {"field2": "me"}}]}}
}

docvalue fields 字段的文档值

为每个命中返回字段的文档值表示,比如:

GET /_search
{"query" : {"match_all": {}},"docvalue_fields" : ["my_ip_field", // 直接用字段名{"field": "my_keyword_field"   // 也可以使用对象标记},{"field": "my_date_field",  // 字段名也支持通配符,比如 *_date_field"format": "epoch_millis"   // 在对象标记中可以自定义格式}]
}

docvalue_fields支持两种两种用法:

  • 直接指定字段名
  • 对象标记

docvalue_fields支持所有启动了文档值的字段,无论这些字段是否被存储。

如果docvalue_fields中指定了未启用文档值的字段,它将尝试从字段数据的缓存中加载值,从而导致该字段的词条加载到内存中,消耗更多的内存。

另外,大部分字段类型不支持自定义格式,但是:

  • Date类型的字段可以指定日期格式
  • Numeric类型的字段可以指定Decimal样式

注意:

docvalue_fields不能加载嵌套对象中的字段,如果某字段的路径中包含嵌套对象,那么无法返回任何数据。要访问嵌套的字段,只能在inner_hits块中使用docvalue_fields

什么是doc values

大部分字段会被默认索引,以备查询。倒排索引允许查找词条,并找到包含词条的相关文档。但是排序,聚合,以及在脚本中访问字段的值要使用的不同的数据访问模式,我们需要查找文档并找到字段中的词条,而不是先找到词条,再找到文档。

文档值是磁盘存储的数据结构,在文档索引时构建。其值与_source字段相同,但是是以列的方式,使其对排序和聚合操作更高效。几乎所有的字段类型都支持文档值,除了analyzed字符串字段。

支持文档值的字段默认都已开启这一特性。如果你确定不需要基于某字段进行排序、聚合,或者在脚本中访问该字段的值,你可以禁用这一特性,以节约磁盘空间。

PUT my_index
// curl -X PUT "localhost:9200/my_index" -H 'Content-Type: application/json' -d'
{"mappings": {"properties": {"status_code": {  // 默认启用文档值"type":       "keyword"},"session_id": { "type":       "keyword","doc_values": false  // 禁用文档值}}}
}

Explain详细信息

指定explaintrue可以查看每次命中的详细计算

GET twitter/_search
{"explain": true, "query": {"term": {"user": "kimchy"}}
}

collapese 字段折叠

基于字段的值折叠搜索结果,相当于分组并排序后,取每组第一个文档。比如下面的查询检索每个用户获赞最高的tweet:

GET /twitter/_search
{"query": {"match": {"message": "elasticsearch"}},"collapse" : {"field" : "user" // 根据user字段折叠},"sort": ["likes"],
}

From, Size

from指定偏移,size指定返回的命中数,可以用于分页

GET /_search
{"from" : 0, "size" : 10,"query" : {"term" : { "user" : "kimchy" }}
}

注意:from + size 不能大于index.max_result_window的默认值10000

###highlight高亮

基本用法:高亮需要指定字段

GET /_search
{"query": {"match": {"content": "mate"}},"highlight": {"fields": {"content":{}}  // 使用默认样式高亮content字段}
}

返回结果如下,默认样式是加<em>标签:

{"took" : 261,"timed_out" : false,"_shards" : {"total" : 18,"successful" : 18,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 2,"relation" : "eq"},"max_score" : 0.8328784,"hits" : [{"_index" : "article","_type" : "_doc","_id" : "2","_score" : 0.8328784,"_source" : {"content" : "huawei mate pro 销量一飞冲天"},"highlight" : {"content" : ["huawei <em>mate</em> pro 销量一飞冲天"]}},{"_index" : "article","_type" : "_doc","_id" : "3","_score" : 0.7942397,"_source" : {"content" : "mate pro 销量以前销量普通"},"highlight" : {"content" : ["<em>mate</em> pro 销量以前销量普通"]}}]}
}

指定高亮文本的摘要长度:

GET post001/_search
{"query": {"multi_match": {"fields": ["title", "content"],"query": "考研"}},"highlight": {"fields": {"content": {"number_of_fragments": 3,  // 返回几个匹配的摘要"fragment_size": 50  // 每个摘要的长度},"title": {}}}}

更多自定义设置参考官网

indices_boost 索引提升

为不同的索引(集)设置不同的提升级别,当一个索引的命中结果比其他索引的命中结果更重要时,可以使用。

GET /_search
{"indices_boost" : [{ "index1" : 1.4 },{ "index2" : 1.3 }]
}

如果指定的索引不存在,会报错。

inner_hits内部命中

join父子字段和nested嵌套字段(对象数组)可以返回不同域内匹配的文档。

inner_hits可以告诉你哪个嵌套对象或者父/子文档导致了特定信息被返回。inner_hits可以定义在nested, has_child, has_parent查询和过滤中。

nested inner hits

示例:

// 定义test001,comments字段类别为nested
PUT test001
{"mappings": {"properties": {"comments": {"type": "nested"}}}
}// 索引文档
PUT test/_doc/1
{"title": "Test title","comments": [  // 对象数组{"author": "kimchy","number": 1},{"author": "nik9000","number": 2}]
}//
POST test001/_search
{"query": {"nested": {  // nested查询"path": "comments","query": {"match": {"comments.number" : 2}},"inner_hits": {} }}
}// 查询结果如下:
{"took" : 34,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 1,"relation" : "eq"},"max_score" : 1.0,"hits" : [{"_index" : "test001","_type" : "_doc","_id" : "1","_score" : 1.0,"_source" : {"title" : "Test title","comments" : [{"author" : "kimchy","number" : 1},{"author" : "nik9000","number" : 2}]},"inner_hits" : {"comments" : {"hits" : {"total" : {"value" : 1,"relation" : "eq"},"max_score" : 1.0,"hits" : [{"_index" : "test001","_type" : "_doc","_id" : "1","_nested" : {  // 内部命中了哪个对象"field" : "comments","offset" : 1},"_score" : 1.0,"_source" : {  // 这个资源是 _nested中命中的那个对象"author" : "nik9000","number" : 2}}]}}}}]}
}

上面的例子中,_nested元数据很关键,因为它定义了这个内部命中来自哪个内部嵌套对象:这里是comments字段中,偏移为1的那个嵌套对象。不过,由于排序和打分,命中位置通常和该对象定义时的位置不一致。

特别要注意的是,嵌套对象存储在根文档中,而根文档在_source字段下,嵌套对象其实没有_source字段。为嵌套对象返回这个字段是有性能开销的,尤其是在size和内部命中的size设置的比默认值大的时候。为了避免这一点,可以在inner_hits中禁止包含_source字段,而是使用docvalue_fields字段。就像这样:

POST test/_search
{"query": {"nested": {"path": "comments","query": {"match": {"comments.text" : "words"}},"inner_hits": {"_source" : false,"docvalue_fields" : ["comments.number"]}}}
}

多层嵌套字段和内部命中

示例:以下comments嵌套字段中又包含一个votes嵌套字段:

// 定义mapping
PUT test
{"mappings": {"properties": {"comments": {"type": "nested","properties": {"votes": {"type": "nested"}}}}}
}// 索引文档
PUT test/_doc/1?refresh
{"title": "Test title","comments": [{"author": "kimchy","text": "comment text","votes": []},{"author": "nik9000","text": "words words words","votes": [{"value": 1 , "voter": "kimchy"},{"value": -1, "voter": "other"}]}]
}// inner hits查询
POST test/_search
{"query": {"nested": {"path": "comments.votes","query": {"match": {"comments.votes.voter": "kimchy"}},"inner_hits" : {}}}
}

返回结果如下:

{...,"hits": {"total" : {"value": 1,"relation": "eq"},"max_score": 0.6931472,"hits": [{"_index": "test","_type": "_doc","_id": "1","_score": 0.6931472,"_source": ...,"inner_hits": {"comments.votes": { "hits": {"total" : {"value": 1,"relation": "eq"},"max_score": 0.6931472,"hits": [{"_index": "test","_type": "_doc","_id": "1","_nested": {"field": "comments","offset": 1,"_nested": {"field": "votes","offset": 0}},"_score": 0.6931472,"_source": {"value": 1,"voter": "kimchy"}}]}}}}]}
}

父子内部命中

示例:

PUT test
{"mappings": {"properties": {"my_join_field": {"type": "join","relations": {"my_parent": "my_child"}}}}
}// 索引父文档
PUT test/_doc/1?refresh
{"content": "from parent balabala","my_join_field": "my_parent"
}// 索引子文档,url中的routing必须是parent的id值
PUT test/_doc/2?routing=1&refresh
{"content": "from child balabala","my_join_field": {"name": "my_child","parent": "1"}
}// has_child搜索,搜索子文档查找父文档
POST test/_search
{"query": {"has_child": {"type": "my_child","query": {"match": {"content": "from child balabala"}},"inner_hits": {}    }}
}// has_parent,基于父文档查找子文档
POST test/_search
{"query": {"has_parent": {"type": "my_parent","query": {"match": {"content": "from parent balabala"}},"inner_hits": {}    }}
}

返回结果:

{...,"hits": {"total" : {"value": 1,"relation": "eq"},"max_score": 1.0,"hits": [  // 命中父文档{"_index": "test","_type": "_doc","_id": "1",  "_score": 1.0,"_source": { "number": 1,"my_join_field": "my_parent"},"inner_hits": {"my_child": {"hits": {"total" : {"value": 1,"relation": "eq"},"max_score": 1.0,"hits": [  // 命中子文档{"_index": "test","_type": "_doc","_id": "2","_score": 1.0,"_routing": "1","_source": {"number": 1,"my_join_field": {"name": "my_child","parent": "1"}}}]}}}}]}
}

min_score

过滤打分低于指定值的文档:

GET /_search
{"min_score": 0.5,"query" : {"term" : { "user" : "kimchy" }}
}

_name 命名查询

过滤上下文和查询上下文中,可以指定_name

GET /_search
{"query": {"bool" : {"should" : [{"match" : { "name.first" : {"query" : "shay", "_name" : "first"} }},{"match" : { "name.last" : {"query" : "banon", "_name" : "last"} }}],"filter" : {"terms" : {"name.last" : ["banon", "kimchy"],"_name" : "test"}}}}
}

post_filter

在搜索结果出来后,再进行过滤(区别于搜索中过滤),具体参见官网的示例

preference

指定在哪个副本分片上执行搜索。

rescore

二次打分有助于提高查询的精度。它应用额外的算法对query和post_filter返回查询结果的TOP-N进行重新排序(不对所有查询结果应用,是为了减少开销)。rescore请求在每个分片返回其结果给协调节点前(该节点负责处理当前请求并汇总结果)执行。

TOP-N可以通过window_size参数指定,默认是10。

原始查询打分和二次打分查询的打分合并为文档的最终打分。

原始查询和二次打分查询的权重可以通过query_weightrescore_query_weight来控制,默认是1

示例:

POST /_search
{"query" : {"match" : {"message" : {"operator" : "or","query" : "the quick brown"}}},"rescore" : {"window_size" : 50,"query" : {"rescore_query" : {"match_phrase" : {"message" : {"query" : "the quick brown","slop" : 2}}},"query_weight" : 0.7,"rescore_query_weight" : 1.2}}
}

打分合并的方式可以由score_mode控制:

  • total 相加(默认值)
  • multiply
  • avg
  • max
  • min

另外,可以依次执行多个二次打分:

POST /_search
{"query" : {"match" : {// ...}}},"rescore" : [ {"window_size" : 100,"query" : {"rescore_query" : {// ...},"query_weight" : 0.7,"rescore_query_weight" : 1.2}}, {"window_size" : 10,"query" : {"score_mode": "multiply","rescore_query" : {// ...}}} ]
}

script fields

自定义字段,并根据脚本返回自定义的值:

GET /_search
{"query" : {"match_all": {}},"script_fields" : {"test1" : {"script" : {"lang": "painless","source": "doc['price'].value * 2"}},"test2" : {"script" : {"lang": "painless","source": "doc['price'].value * params.factor","params" : {"factor"  : 2.0}}}}
}

访问字段时,推荐使用doc['field'].value的方式,当然也可以通过params['_source']['field']的方式,比如:

GET /_search{"query" : {"match_all": {}},"script_fields" : {"test1" : {"script" : "params['_source']['message']"}}}

二者的区别是,doc['field'].value的方式是将目标字段的词条加载到内存并缓存,执行速度更快。另外,这种方式仅适用于简单数据类型的字段(比如,不能是json),且对于不作分词处理或者单词条的字段才有意义(也就不能是text类型)。

不推荐使用_source的方式,因为要加载并解析整个文档,会很慢。

scroll

类似于传统数据库的游标。scroll用于处理大量的数据,比如分页,比如将一个索引的文档重新索引到另一个索引,分批来索引。

示例:

POST /twitter/_search?scroll=1m  // 指定保持搜索上下文1分钟
{"size": 100,  // 指定分页大小"query": {"match" : {"title" : "elasticsearch"}}
}

要使用scroll,必须在第一次请求的查询字符串中指定?scroll,来告诉ES保持搜索上下文。ES返回的结果中,会包含一个_scroll_id,在调用scroll API时,需要传递这个id来检索下一批的结果:

POST /_search/scroll
{"scroll" : "1m", "scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ=="
}

注意,这次请求不需要指定索引名,因为第一次请求中已经指定了(猜测scroll_id中包含该信息)。scroll参数告诉ES,再保持上下文1分钟。

更多查看官网

search_after

分页可以使用fromsize完成,但是随着分页数越来越大,开销也将无法接受。ES默认的index.max_result_window值是10000就是出于这个考虑。相比之下,对于大的分页,更推荐使用scroll,但是scroll有上下文开销,并且不推荐用于用户的实时请求。而search_after通过实时游标可以解决这个问题,其思路是使用上一页的结果来帮助检索下一页的数据。

示例:

GET twitter/_search
{"size": 10,"query": {"match" : {"title" : "elasticsearch"}},"sort": [{"date": "asc"},{"tie_breaker_id": "asc"}      ]
}

注意:

排序的tiebreaker参数应该使用能唯一标识文档的字段,否则可能出现排序未定义,导致缺失或者重复结果。_id字段具有唯一值,但是不推荐直接作为tiebreaker使用。需要知道的是,search_after在查找文档时,只需要全部或者部分匹配tiebreaker提供的值。因此,若一个文档tiebreaker值是"654323",而你指定search_after为"654",那么将仍然匹配该文档,并返回它之后的结果。建议在另一个字段中重复_id字段的内容,并使用这个新字段作为tiebreaker用于排序。

以上请求的结果会包含文档排序值(sort values)的数组,这些排序值可以用在search_after参数中。比如我们可以将最后一个文档的排序值传给"search_after",以获取下一页的数据:

GET twitter/_search
{"size": 10,"query": {"match" : {"title" : "elasticsearch"}},"search_after": [1463538857, "654323"],"sort": [{"date": "asc"},{"tie_breaker_id": "asc"}]
}

如果使用了search_after,from参数只能设置为0或者-1

search_after无法满足随意跳页的要求,类似于scroll API。不同之处在于,search_after是无状态的,因此索引的更新或者删除,可能会改变排序。

也可使用打分(搜索时默认按打分倒序)和id来排序:

"sort": [{"_score": {"order": "desc"}},{"_id": {"order":"asc"}}
]

注意:search_after和collapse不能同时使用!!!

seq_no_primary_term

返回匹配文档最后一次修改的序号和primary term(和并发加锁有关,具体参考ES的Document API):

GET /_search
{"seq_no_primary_term": true,"query" : {"term" : { "user" : "kimchy" }}
}

sort

排序在字段上定义,对于特殊字段,_score根据打分排序,_doc根据索引排序。

示例:

PUT /my_index
{"mappings": {"properties": {"post_date": { "type": "date" },"user": {"type": "keyword"},"name": {"type": "keyword"},"age": { "type": "integer" }}}
}
GET /my_index/_search
{"sort" : [{ "post_date" : {"order" : "asc"}},"user",{ "name" : "desc" },{ "age" : "desc" },"_score"],"query" : {"term" : { "user" : "kimchy" }}
}

_doc没啥用但确是最高效的排序。如果你不关心文档返回顺序,建议使用_doc排序,在scroll中尤其如此。

sort values

每个文档的排序值会在响应中返回,可用于search_after API

sort order

  • asc 升序,默认排序方式
  • desc 倒序,根据_score排序默认是倒序

sort mode option

ES支持就数组或多值字段排序,mode选项可以控制用哪个值用来排序:

  • min 选择最小值
  • max 选择最大值
  • sum 加总值(仅适用于数字数组)
  • avg 平均值(仅适用于数字数组)
  • median 中位数(仅适用于数字数组)

升序排序时,默认模式是min,倒序排序时,默认模式是max

更多查看官网

_source 过滤

控制_source字段的返回,可以禁止返回,设置为flase,也可以指定返回哪些字段,丢弃哪些字段:

GET twitter/_search
{"_source": {"includes": ["user", "post_date"],  // 返回的字段"excludes": "message"  // 丢弃的字段}, "query": {"match_all": {}}
}

另外,字段还支持通配符匹配

stored_fields

stored_fields是那些在mapping中指定为stored的字段(默认false),不推荐使用。建议使用_source 过滤。

track_total_hits

计算有多少匹配文档,可以指定为true精确计算,也可以给定具体数值。具体查看官网

version

返回文档的版本

GET /_search
{"version": true,"query" : {"term" : { "user" : "kimchy" }}
}

Search Template

_search/template接口允许使用模板字符预渲染搜索请求:

GET /_search/template
{"source" : {"query": { "match" : { "{{my_field}}" : "{{my_value}}" } },"size" : "{{my_size}}"},"params" : {"my_field" : "message","my_value" : "some message","my_size" : 5}
}

或者:

GET _search/template
{"source": {"query": {"term": {"message": "{{query_string}}"}}},"params": {"query_string": "search for these words"}
}

JSON参数

toJson函数可以将字典或者数组转为为JSON表示,比如:

GET _search/template
{"source": "{ \"query\": { \"terms\": {{#toJson}}statuses{{/toJson}} }}","params": {"statuses": [ "pending", "published" ]}
}

将被渲染为:

{"query": {"terms": {"status": ["pending","published"]}}
}

_msearch

_msearch,在一个API中执行多个查询请求。

其他:

  • copy_to 可以将多个字段的内容合并到一个新字段,在查询中使用新字段查询。
  • 精确值和全文本
    • 精确值不需要做分词的处理,就是ES中的keyword

      • 数字,日期,状态,具体字符串(比如"apple store"),没有必要作分词处理。
    • 全文本会分词,ES中的text

Search API相关推荐

  1. Elasticsearch之Search API

    Search API 实现对es中存储的数据进行查询分析,endpoint为 _search,如下图所示: 查询主要有两种形式 - URI Search - 操作简便,方便通过命令行测试 - 仅包含部 ...

  2. 申请Bing Search API

    地址:https://datamarket.azure.com/home 没有帐号先注册一个,然后登录. 1:在数据中订阅Bing Search API,如果找不到就使用这个地址: https://d ...

  3. Windows Azure Marketplaces上的Bing Search API可用啦!

    Windows Azure Marketplace上的Bing Search API 现在可用啦!通过此服务,你可以嵌入web.图像.新闻和视频搜索结果,以及相关的搜索和拼写建议来创建独特的应用程序和 ...

  4. Elasticsearch:Async search API

    当我们想要执行持续时间较长的查询时,执行异步操作是一个很好的选择. 在这篇文章中,我们将学习如何管理异步查询.异步操作由 async search API 执行. 异步搜索 API 具有与 _sear ...

  5. Elasticsearch Search API说明

    一.Search API分类 二.URI search 查询说明 一.Search API分类 Elasticsearch中 Search API分为 Search URI 和Request Body ...

  6. ElasticSearch: Search API 查询用法详解

    Search API ElasticSearch 为了搜索提供了一些原始的 API,主要是有两大类 URL Search URL Search 类似 http 的get请求,是将请求参数放到 URL ...

  7. Elasticsearch Search API之(Request Body Search 查询主体)

    作者介绍:<RocketMQ技术内幕>作者,中间件兴趣圈微信公众号维护者,文末有对应的二维码,关注后可以与作者更好的互动. 本文有点长,看完可能需要点耐心,本文详细介绍了es三种分页方式. ...

  8. 第 9 部分: 使用 Google Ajax Search API

    发出异步请求并不意味着只是与您自己的服务器端程序交互.其实也可以与一些公共 API,例如来自 Google 或 Amazon 的 API 进行通信,从而为 Web 应用程序增加您自己的脚本和服务器端程 ...

  9. 如何使用bing search api来进行网页开发

    Bing 搜索引擎为微软旗下推出,集网页,图片,视频,新闻等等搜索的结果,使用bing search api的前提是拥有微软账号,微软账号的注册可以使用qq邮箱或者gmail(谷歌旗下的邮箱)进行注册 ...

  10. 通过 iTunes Search API 检测版本更新

    更新提示-w200 苹果对版本更新的限定 若你的 app 中有 用户可以主动检测更新的入口, 苹果审核时会被拒, 偶然间发现 手机QQ 的一个作弊手段, 当你手机上的 QQ 有更新版本时,在 app ...

最新文章

  1. 写一个不能被继承的类(友元的不可继承性)
  2. SQL语句正常,在Navicat中运行正常,但是在后台运行,无法查询出数据,也不报错...
  3. Jenkins中连接Git仓库时提示:无法连接仓库:Error performing git command: git ls-remote -h
  4. SpringCloud源码:Ribbon负载均衡分析
  5. leetcode刷题日记-三个无重叠子数组的最大和
  6. 人工智能火灾报警器_使用AI进行准确的火灾预测
  7. 谷歌浏览器如何正确离线网页
  8. VLAN中tagged与untagged的处理
  9. 可任意设置时间的ppt倒计时软件
  10. 精灵混合加密系统_混合云的数据备份
  11. 前端图片压缩(几乎无损)
  12. 关于铁路订票系统如何改善设计的讨论
  13. python 摄氏度和华氏度温度转换案例
  14. 有哪些比较安全可靠的PDF编辑器
  15. iOS底层系统:虚拟内存
  16. 携程福利变噩梦 上海妇联:严肃处理旗下杂志
  17. Jmeter的使用(一)
  18. VMS(VELO) tips[转载]
  19. 使用代码操作Excel文件(easyExcel)
  20. 【文本处理 词频统计】python 实现词频统计

热门文章

  1. (王道408考研操作系统)第二章进程管理-第三节6:经典同步问题之生产者与消费者问题
  2. LeetCode 605 种花问题
  3. Java 线程实例一(查看线程是否存活、获取当前线程名称、状态监测、线程优先级设置、死锁及解决方法、获取线程id、线程挂起)
  4. Java 集合List、Set、HashMap操作三(查找List中的最大最小值、遍历HashTable、List元素替换、List查找位置)
  5. shell获取执行脚本路径
  6. 使用hexo创建blog
  7. Linux忘记root密码怎么办?
  8. 《架构之美》学习随笔:设计第一步
  9. GNU make manual 翻译( 一百五十五)
  10. varchar和Nvarchar区别