【工作笔记】从零开始学ElasticSearch( 十)—— 高级扩展:搜索(Basic)

来源:互联网 发布:淘宝助理怎么设置主图 编辑:程序博客网 时间:2024/06/05 14:09

搜索

每个文档里的字段都会被索引并被查询。而且不仅如此。在简单查询时,Elasticsearch可以使用所有的索引,以非常快的速度返回结果。

搜索(search)可以:

  1. 在类似于gender或者age这样的字段上使用结构化查询,join_date这样的字段上使用排序,就像SQL的结构化查询一样。
  2. 全文检索,可以使用所有字段来匹配关键字,然后按照关联性(relevance)排序返回结果。
  3. 或者结合以上两条。

很多搜索都是开箱即用的,为了充分挖掘Elasticsearch的潜力,你需要理解以下三个概念

概念                  解释映射(Mapping)        数据在每个字段中的解释说明分析(Analysis)       全文是如何处理的可以被搜索的领域特定语言查询(QueryDSL)  Elasticsearch使用的灵活的、强大的查询语言

空搜索

最基本的搜索API表单是空搜索(empty search),它没有指定任何的查询条件,只返回集群索引中的所有文档

GET /_search

响应内容

{   "hits" : {      "total" :       14,      "hits" : [        {          "_index":   "us",          "_type":    "tweet",          "_id":      "7",          "_score":   1,          "_source": {             "date":    "2014-09-17",             "name":    "John Smith",             "tweet":   "The Query DSL is really powerful and flexible",             "user_id": 2          }       },        ... 9 RESULTS REMOVED ...      ],      "max_score" :   1   },   "took" :           4,   "_shards" : {      "failed" :      0,      "successful" :  10,      "total" :       10   },   "timed_out" :      false}

hits

响应中最重要的部分是hits,它包含了total字段来表示匹配到的文档总数,hits数组还包含了匹配到的前10条数据

hits数组中的每个结果都包含_index、_type和文档的_id字段,被加入到_source字段中这意味着在搜索结果中我们将可以直接使用全部文档。这不像其他搜索引擎只返回文档ID,需要你单独去获取文档。

每个节点都有一个_score字段,这是相关性得分(relevance score),它衡量了文档与查询的匹配程度。默认的,返回的结果中关联性最大的文档排在首位;这意味着,它是按照_score降序排列的。这种情况下,我们没有指定任何查询,所以所有文档的相关性是一样的,因此所有结果的_score都是取得一个中间值1

max_score指的是所有文档匹配查询中_score的最大值

took

took告诉我们整个搜索请求花费的毫秒数

shards

_shards节点告诉我们参与查询的分片数(total字段),有多少是成功的(successful字段),有多少的是失败的(failed字段)。通常我们不希望分片失败,不过这个有可能发生。如果我们遭受一些重大的故障导致主分片和复制分片都故障,那这个分片的数据将无法响应给搜索请求。这种情况下,Elasticsearch将报告分片failed,但仍将继续返回剩余分片上的结果

timeout

time_out值告诉我们查询超时与否。一般的,搜索请求不会超时。如果响应速度比完整的结果更重要,你可以定义timeout参数为10或者10ms(10毫秒),或者1s(1秒)

GET /_search?timeout=10ms

注:需要注意的是timeout不会停止执行查询,它仅仅告诉你目前顺利返回结果的节点然后关闭连接。在后台,其他分片可能依旧执行查询,尽管结果已经被发送

多索引和多类别

你注意到空搜索的结果中不同类型的文档——user和tweet——来自于不同的索引——us和gb。

通过限制搜索的不同索引或类型,我们可以在集群中跨所有文档搜索

/_search

在所有索引的所有类型中搜索

/gb/_search

在索引gb的所有类型中搜索

/gb,us/_search

在索引gb和us的所有类型中搜索

/g*,u*/_search

在以g或u开头的索引的所有类型中搜索

/gb/user/_search

在索引gb的类型user中搜索

/gb,us/user,tweet/_search

在索引gb和us的类型为user和tweet中搜索

/_all/user,tweet/_search

当你搜索包含单一索引时,Elasticsearch转发搜索请求到这个索引的主分片或每个分片的复制分片上,然后聚集每个分片的结果。搜索包含多个索引也是同样的方式——只不过或有更多的分片被关联

搜索一个索引有5个主分片和5个索引各有一个分片事实上是一样的。

分页

size: 结果数,默认10
from: 跳过开始的结果数,默认0

如果你想每页显示5个结果,页码从1到3

GET /_search?size=5GET /_search?size=5&from=5GET /_search?size=5&from=10

在集群系统中深度分页

为了理解为什么深度分页是有问题的,让我们假设在一个有5个主分片的索引中搜索。当我们请求结果的第一页(结果1到10)时,每个分片产生自己最顶端10个结果然后返回它们给请求节点(requesting node),它再排序这所有的50个结果以选出顶端的10个结果。
现在假设我们请求第1000页——结果10001到10010。工作方式都相同,不同的是每个分片都必须产生顶端的10010个结果。然后请求节点排序这50050个结果并丢弃50040个!+

你可以看到在分布式系统中,排序结果的花费随着分页的深入而成倍增长。这也是为什么网络搜索引擎中任何语句不能返回多于1000个结果的原因。

search API有两种表单:一种是“简易版”的查询字符串(query string)将所有参数通过查询字符串定义,另一种版本使用JSON完整的表示请求体(request body),这种富搜索语言叫做结构化查询语句(DSL)

例如这个语句查询所有类型为tweet并在tweet字段中包含elasticsearch字符的文档

GET /_all/tweet/_search?q=tweet:elasticsearch

下一个语句查找name字段中包含”john”和tweet字段包含”mary”的结果。实际的查询只需要:

+name:john +tweet:mary

“+”前缀表示语句匹配条件必须被满足。类似的”-“前缀表示条件必须不被满足。所有条件如果没有+或-表示是可选的——匹配越多,相关的文档就越多

_all字段

返回包含”mary”字符的所有文档的简单搜索:

GET /_search?q=mary
0 0
原创粉丝点击