ElasticSearch(五)--搜索Search
2016-05-14 19:11
543 查看
前边的学习,我们已经可以将ElasticSearch作为一个分布式存储系统使用,但是ES的真正强大之处在于可以在混乱的数据中找出有意义的信息.
每个文档里的字段都会被索引并被查询,关于搜索Search,可以做:
结构化查询:比如在gender性别和年龄age这样的字段上使用结构化查询,在join_date这样的字段上使用排序.
全文查询:可以使用所有字段来匹配关键字,然后按照关联性relevance排序返回结果.
也可以两者结合使用.
搜索都是开箱即用的,为了深入了解ES的潜力,需要三个概念:
映射Mapping:数据在每个字段中的解释说明
分析Analysis:全文是如何被处理,被搜素的
特定领域语言查询Query DSL(Domian Specific Language):ES灵活强大的查询语言.
这三个概念每一个都是巨大的话题,后续详细学习,本章节简单介绍.
下边详细学习search API
hits字段是响应中最重要的一部分,它包含total字段来表示匹配到的文档总数;max_score是所有匹配文档中相关性最高的值;hits数组包含了匹配到的前10条数据,数组的每个元素代表一个文档,其中_score为文档相关性指标,因为是空搜索,所以所有文档的_score都为1;
took字段,指请求花费的时间,单位为毫秒;
_shards代表参与查询的分片数的情况,total是参与的总分片数,successful是成功的分片数,通常我们不希望分片失败,但也有可能发生,如果硬件遭受大的故障导致主分片和复制分片都失效,那么这个分片将无法响应请求,ES将该分配报告为failed,但仍然继续返回剩余分片上的结果.
timed_out告诉我们查询是否超时;一般情况不会超时;如果要求的响应速度比结果更重要,可以在搜索的时候指定时间限,为10或者10ms,或者1s
ES将返回在时间限前查询到的结果.
注意:超过指定的timeout之后,不会停止执行查询,它仅顺利返回目前查询到的结果,然后关闭连接.在后台其他分片可能依旧查询操作;
使用超时是因为对业务的响应速度需求比结果重要,但并不是中断需要长时间进行的查询.
类型user属于索引us,类型tweet属于索引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:在所有的索引的user,tweet类型中搜索
当节点收到搜索请求后,节点转发请求到索引的主分片和复制分片上,然后收集每个分片的结果.
ES的请求URL接受size和from参数,
size:结果数,默认为10
from :跳过的数目,默认为0
所以在没指定size和from参数时,返回开始的10个相关文档.
如果显示每页五个结果,页码从1到3:
一个请求常涉及到多个分片,每个分片都会生成自己的排序结果,它们需要再次集中起来排序以返回请求需要的结果给客户端.
深度分页存在的:
假设有五个分片,每一页返回10个结果,那么在请求第一页时(也就是top10的结果),每个分片需要各自产生10个结果,然后每个分片把产生的这10个结果返回个请求节点,请求节点对收到的10*5=50个结果再进行排序,选择前10个返回客户端;
但是当请求第1001页时,也就是请求(10000-10010)的结果,同样每个分片产生10010个结果,请求节点收到10010*5=50050的结果,请求节点对这50050个结果进行排序,然后返回第1000-10010的结果;
显然排序的花费随着分页的加深而成倍增长.
4. query-string方法
search API有两种方式:
精简版的,查询字符串query-string方法,通过在请求URL后加参数的方式;
请求体方式,使用一个JSON格式的请求体,这种成为DSL查询语言.
查询字符串方法在命令行下运行即席查询ad hoc queries特别有用.
查询所有类型为tweet,并且字段tweet中包含elasticsearch字符的文档:
如果要是选择不满足条件的,比如name不包含join的:
比如,name包含join但tweet不包含jmary的:
_all字段:
返回所有包含mary字符串的文档,无论是在哪个字段中包含,只有有就返回:
那么ES是如何实现这功能的呢?实际上文档有一个特殊的_all字段,该字段把所有的字段的数据连接成以一个大的字符串,匹配时通过_all字段进行匹配.
例如文档内容:
结果是一样的.
更复杂的搜索
搜索要求:
搜索命令:
可以看出字符串查询是非常强大的,它在命令行下一次性查询或者开发模式下非常有用.
但也可以看出,其是非常脆弱的,一点的符号错误都有可能到是查询失败.
还有就是安全性问题,不建议直接暴露查询字符串给用户,除非用户对集群可信.
所以取而代之,我们一般使用全功能的请求体API的方式,在学习请求体时,先了解数据是如何在ES中被索引的.
每个文档里的字段都会被索引并被查询,关于搜索Search,可以做:
结构化查询:比如在gender性别和年龄age这样的字段上使用结构化查询,在join_date这样的字段上使用排序.
全文查询:可以使用所有字段来匹配关键字,然后按照关联性relevance排序返回结果.
也可以两者结合使用.
搜索都是开箱即用的,为了深入了解ES的潜力,需要三个概念:
映射Mapping:数据在每个字段中的解释说明
分析Analysis:全文是如何被处理,被搜素的
特定领域语言查询Query DSL(Domian Specific Language):ES灵活强大的查询语言.
这三个概念每一个都是巨大的话题,后续详细学习,本章节简单介绍.
下边详细学习search API
1. 空搜索
最基本的search API是空搜索empty search,它没有指定任何搜索条件,返回的是集群索引中所有的文档.GET /_search响应内容类似于:
{ "took": 15, "timed_out": false, "_shards": { "total": 15, "successful": 15, "failed": 0 }, "hits" : { "total" : 14, "max_score" : 1 "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 ... ], }, }
hits字段是响应中最重要的一部分,它包含total字段来表示匹配到的文档总数;max_score是所有匹配文档中相关性最高的值;hits数组包含了匹配到的前10条数据,数组的每个元素代表一个文档,其中_score为文档相关性指标,因为是空搜索,所以所有文档的_score都为1;
took字段,指请求花费的时间,单位为毫秒;
_shards代表参与查询的分片数的情况,total是参与的总分片数,successful是成功的分片数,通常我们不希望分片失败,但也有可能发生,如果硬件遭受大的故障导致主分片和复制分片都失效,那么这个分片将无法响应请求,ES将该分配报告为failed,但仍然继续返回剩余分片上的结果.
timed_out告诉我们查询是否超时;一般情况不会超时;如果要求的响应速度比结果更重要,可以在搜索的时候指定时间限,为10或者10ms,或者1s
GET /_search?timeout=10ms
ES将返回在时间限前查询到的结果.
注意:超过指定的timeout之后,不会停止执行查询,它仅顺利返回目前查询到的结果,然后关闭连接.在后台其他分片可能依旧查询操作;
使用超时是因为对业务的响应速度需求比结果重要,但并不是中断需要长时间进行的查询.
2. 多索引多类别搜索
通过限制搜索的索引或类型,可以在集群中跨所有文档搜索.ES通过转发请求到集群中主分片和复制分片上,收集结果后选择顶部的10个结果返回给客户端.类型user属于索引us,类型tweet属于索引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:在所有的索引的user,tweet类型中搜索
当节点收到搜索请求后,节点转发请求到索引的主分片和复制分片上,然后收集每个分片的结果.
3. 分页
ES默认只在响应中返回top10的相关文档,如何更具应用的需要返回其他文档呢?就像SQL中LIMIT关键词的功效一样.ES的请求URL接受size和from参数,
size:结果数,默认为10
from :跳过的数目,默认为0
所以在没指定size和from参数时,返回开始的10个相关文档.
如果显示每页五个结果,页码从1到3:
GET /_search?size=5 GET /_search?size=5&from=5 GET /_search?size=5&from=10这里需要注意的问题,注意分页太深,和一次请求结果太多的问题.
一个请求常涉及到多个分片,每个分片都会生成自己的排序结果,它们需要再次集中起来排序以返回请求需要的结果给客户端.
深度分页存在的:
假设有五个分片,每一页返回10个结果,那么在请求第一页时(也就是top10的结果),每个分片需要各自产生10个结果,然后每个分片把产生的这10个结果返回个请求节点,请求节点对收到的10*5=50个结果再进行排序,选择前10个返回客户端;
但是当请求第1001页时,也就是请求(10000-10010)的结果,同样每个分片产生10010个结果,请求节点收到10010*5=50050的结果,请求节点对这50050个结果进行排序,然后返回第1000-10010的结果;
显然排序的花费随着分页的加深而成倍增长.
4. query-string方法
search API有两种方式:精简版的,查询字符串query-string方法,通过在请求URL后加参数的方式;
请求体方式,使用一个JSON格式的请求体,这种成为DSL查询语言.
查询字符串方法在命令行下运行即席查询ad hoc queries特别有用.
查询所有类型为tweet,并且字段tweet中包含elasticsearch字符的文档:
GET /_all/tweet/_search?q=tweet:elasticsearch如果还想查找name中包含join,tweet中包含mary的文档:
GET /_all/tweet/_search?q=name:join+tweet:mary使用+符号连接,结果集为两个条件的合集,即有的结果文档中只匹配一个条件.
如果要是选择不满足条件的,比如name不包含join的:
GET /_all/tweet/_search?q=-name:join
比如,name包含join但tweet不包含jmary的:
GET /_all/tweet/_search?q=name:join+-tweet:mary注意使用+号连接 -tweet:mary
_all字段:
返回所有包含mary字符串的文档,无论是在哪个字段中包含,只有有就返回:
GET /_search?q=mary
那么ES是如何实现这功能的呢?实际上文档有一个特殊的_all字段,该字段把所有的字段的数据连接成以一个大的字符串,匹配时通过_all字段进行匹配.
例如文档内容:
{ "tweet": "However did I manage before Elasticsearch?", "date": "2014-09-14", "name": "Mary Jones", "user_id": 1 }这个_all字段为:
"However did I manage before Elasticsearch? 2014-09-14 Mary Jones 1"实际上请求就是:
GET /_search?q=_all:mary
结果是一样的.
更复杂的搜索
搜索要求:
name字段包含
"mary"或
"john"
date晚于
2014-09-10
_all字段包含
"aggregations"或
"geo"
搜索命令:
GET /_search?q=name:(mary john) +date:>2014-09-10 +(aggregations geo)但实际上(mary join)中间的空格并不正确,使用+号反而可以运行,日期的比较也是错误的:
GET /_search?q=name:(mary+john) +(aggregations+geo)不知道日期如何比较...
可以看出字符串查询是非常强大的,它在命令行下一次性查询或者开发模式下非常有用.
但也可以看出,其是非常脆弱的,一点的符号错误都有可能到是查询失败.
还有就是安全性问题,不建议直接暴露查询字符串给用户,除非用户对集群可信.
所以取而代之,我们一般使用全功能的请求体API的方式,在学习请求体时,先了解数据是如何在ES中被索引的.
相关文章推荐
- Java反射详解,从理论到实践
- 组合模式
- java基础学习总结六(对象与类、类的属性与方法)
- Android(java)学习笔记207:Android下的属性动画(Property Animation)
- 2016百度之星资格赛1001
- 使用design.widget.TabLayout
- 第十一周进度条
- 语法分析(6)...
- L3-2 堆栈 团体程序设计天梯赛-练习集
- ElasticSearch(四)--分布式文档存储
- 基于SSH框架开发的《高校大学生选课系统》的质量属性的实现
- 如何利用hibernate3解决数据库丢失更新问题?
- JVM监控工具介绍
- PHP笔记②所有输出语句
- ORA-03113
- 仿美团外卖,饿了吗 两个ListView联动,左边点击切换右边,右边滑动切换左边
- RMQ (范 围 最 值 问 题)
- 第17章 KDE的Qt
- java反射机制
- 关于三年工作的一点点感悟