elasticsearch查询,elasticsearch查询语句
ElasticSearch常用查询方法总结
基于词项的查询:不需要分析阶段,对单个词项进行操作,在倒排索引中查找准确词项。
Terms Query:在给定字段内查询并返回准确符合一个或多个词项的查询结果。
Fuzzy Query:返回与给定词项 相似 的结果。相似程度用Levenshtein编辑距离来衡量。
1编辑距离指一个字符的变化,包括:
Fuzzy Query会创建一系列可能出现的,编辑距离为1的变化后的词项,然后用这些词项进行精确查询以获得最终结果。
Wildcard Query:返回符合通配符表达式的查询结果。使用?代替单个字符,*代替零个或几个字符。
基于全文的查询:高层查询,要先了解字段映射的信息。如果查询一个未分析的精确值字符串字段,会将整个查询字符串作为单个词项对待。如果查询一个已分析的精确值字符串字段,会先将查询字符串传递到一个合适的分析器, 然后生成一个供查询的词项列表。
Match Query:是一个高级全文查询,它既能处理全文字段,又能处理精确字段。Match Query主要的应用场景就是进行全文搜索,但无论需要查询什么字段, Match Query都应该会是首选的查询方式。
Query String Query:使用句法将给定的查询条件按And或Or的方式进行分析和拆分,返回包含查询字符串的结果。
Match Phrase Query:会分析文本,再从分析后的文本中生成phrase查询。
复合查询:组合查询语句,使查询结果符合多项标准,支撑更复杂的查询条件。
Bool Query:对查询语句进行与或非的组合。包含关键词must(and), should(or), must_not(not)。
Table1 Comparison of ES Query Methods
Reference List:
Elasticsearch的几种查询方式及其参数说明
查询方式:
1、query string search?
1.1 GET /索引/类型/_search
其中:
took:耗费时间
timed_out: 是否超时
?_shards:数据分片信息
????????totle:被查询的分片数
????????successful:成功执行查询的分片数
????????failed:失败执行查询的分片数
hits.total:查询结果的数量
hits.max_score:对于查询条件的匹配度,分数越高越匹配
hits.hits:所有匹配到的数据
? ? ? ??"_index":所在索引?
? ? ? ? "_type":对应的类型
? ? ? ? "_id":主键ID
? ? ? ? "_score":匹配分数
? ? ? ? "_source":数据资源
1.2 GET /索引/类型/_search?q=field:xxxsort=field:desc
? ? 查询语句说明:
? ? ? ? q代表查询条件,q等于键值对
? ? ? ? sort代表排序,field代表字段,desc代表排序方式
2 query DSL(Domain Specified Language)
? ? 2.1 GET /索引/类型/_search?
? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? "query": { // 查询条件
? ? ? ? ? ? ? ? ? ? ? ? ? ? "match":{ // 改为match_all 查全部
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "field": "XXX"
????????????????????????????}
????????????????????},
? ? ? ? ? ? ? ? ? ? “_source”: [ "field1", "field2" ], // 指定结果列
? ? ? ? ? ? ? ? ? ? "hightlight": { // 查询结果高亮显示
? ? ? ? ? ? ? ? ? ? ? ? ? ? "pre_tags" : "p class='red'", // 自定义高亮标签开始
? ? ? ? ? ? ? ? ? ? ? ? ? ? "post_tags" : "/p",?// 自定义高亮标签结尾
? ? ? ? ? ? ? ? ? ? ? ? ? ? "fields": { // 要高亮显示的字段
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "field": {} // 实际字段
? ? ? ? ? ? ? ? ? ? ? ? ? ? }
????????????????????},
? ? ? ? ? ? ? ? ? ? "sort": [ // 排序条件
? ? ? ? ? ? ? ? ? ? ? ? ? ? {"parice": "desc"}
????????????????????],
? ? ? ? ? ? ? ? ? ? “form”: 1, // 第几页
? ? ? ? ? ? ? ? ? ? "size": 2 // 每页几天
????????????}
3??query filter
? ??????GET /索引/类型/_search?
? ? ? ? {
? ? ? ? ? ? ? ? “bool”: {
? ? ? ? ? ? ? ? ? ? ? ? "must": { // 必须匹配
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "match": {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "field": "XXX"
????????????????????????????????}
????????????????????????},
? ? ? ? ? ? ? ? ? ? ? ? "filter": { // 筛选
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "range": { // 范围
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "field": { "gt": "22" } // gt代表大于
????????????????????????????????}
????????????????????????}
????????????????}
????????}
4 full-text search 全文检索
? ??????GET /索引/类型/_search?
? ? ? ? {
? ? ? ? ? ? ? ? “query”: {
? ? ? ? ? ? ? ? ? ? ? ? "match": { "field": "XXX OOOO" } // 查询匹配全文中的field字段,包含OOOO和XXX的数据信息,其中包含XXX OOOO的数据的_score分数最高,匹配度最高,原理为,数据进入时会将field字段的内容进行分词,然后根据分出来的每个词去匹配
????????????????}
????????}
5 phrase search (短语搜索)
? ??????GET /索引/类型/_search?
? ????? {
? ? ? ? ? ????? “query”: {
? ? ? ? ? ? ? ? ? ????? "macth_phrase" : { // 只匹配XXX OOOO这个短句,而全文检索是除此之外,还会将包含XXX和包含OOOO的也都匹配出来
? ? ? ? ? ? ? ? ? ? ? ? ? ??????"field": "XXX OOOO"
????????????????????????}
????????????????}
????????}
ElasticSearch查询流程详解
前面已经介绍了ElasticSearch的写入流程,了解了ElasticSearch写入时的分布式特性的相关原理。ElasticSearch作为一款具有强大搜索功能的存储引擎,它的读取是什么样的呢?读取相比写入简单的多,但是在使用过程中有哪些需要我们注意的呢?本篇文章会进行详细的分析。
在前面的文章我们已经知道ElasticSearch的读取分为两种GET和SEARCH。这两种操作是有一定的差异的,下面我们先对这两种核心的数据读取方式进行一一分析。
(图片来自官网)
以下是从主分片或者副本分片检索文档的步骤顺序:
注意:
在协调节点有个http_server_worker线程池。收到读请求后它的具体过程为:
数据节点上有一个get线程池。收到了请求后,处理过程为:
注意:
get过程会加读锁。处理realtime选项,如果为true,则先判断是否有数据可以刷盘,然后调用Searcher进行读取。Searcher是对IndexSearcher的封装在早期realtime为true则会从tranlog中读取,后面只会从index的lucene读取了。即实时的数据只在lucene之中。
对于Search类请求,ElasticSearch请求是查询lucene的Segment,前面的写入详情流程也分析了,新增的文档会定时的refresh到磁盘中,所以搜索是属于近实时的。而且因为没有文档id,你不知道你要检索的文档在哪个分配上,需要将索引的所有的分片都去搜索下,然后汇总。ElasticSearch的search一般有两个搜索类型
所有的搜索系统一般都是两阶段查询:
第一阶段查询到匹配的docID,第二阶段再查询DocID对应的完整文档。这种在ElasticSearch中称为query_then_fetch,另一种就是一阶段查询的时候就返回完整Doc,在ElasticSearch中叫query_and_fetch,一般第二种适用于只需要查询一个Shard的请求。因为这种一次请求就能将数据请求到,减少交互次数,二阶段的原因是需要多个分片聚合汇总,如果数据量太大那么会影响网络传输效率,所以第一阶段会先返回id。
除了上述的这两种查询外,还有一种三阶段查询的情况。
搜索里面有一种算分逻辑是根据TF和DF来计算score的,而在普通的查询中,第一阶段去每个Shard中独立查询时携带条件算分都是独立的,即Shard中的TF和DF也是独立的。虽然从统计学的基础上数据量多的情况下,每一个分片的TF和DF在整体上会趋向于准确。但是总会有情况导致局部的TF和DF不准的情况出现。
ElasticSearch为了解决这个问题引入了DFS查询。
比如DFS_query_then_fetch,它在每次查询时会先收集所有Shard中的TF和DF值,然后将这些值带入请求中,再次执行query_then_fetch,这样算分的时候TF和DF就是准确的,类似的有DFS_query_and_fetch。这种查询的优势是算分更加精准,但是效率会变差。
另一种选择是用BM25代替TF/DF模型。
在ElasticSearch7.x,用户没法指定以下两种方式: DFS_query_and_fetch 和 query_and_fetch 。
注:这两种算分的算法模型在《ElasticSearch实战篇》有介绍:
这里query_then_fetch具体的搜索的流程图如下:
(图片来自官网)
查询阶段包含以下四个步骤:
以上就是ElasticSearch的search的详细流程,下面会对每一步进行进一步的说明。
协调节点处理query请求的线程池为:
http_server_work
负责该解析功能的类为:
org.elasticsearch.rest.action.search.RestSearchAction
主要将restquest的参数封装成SearchRequest
这样SearchRequest请求发送给TransportSearchAction处理
将索引涉及到的shard列表或者有跨集群访问相关的shard列表合并
如果有多个分片位于同一个节点,仍然会发送多次请求
shardsIts为搜索涉及的所有分片,而shardRoutings.nextOrNull()会从分片的所有副本分片选出一个分片来请求。
onShardSuccess对收集到的结果进行合并,这里需要检查所有的请求是否都已经有了回复。
然后才会判断要不要进行executeNextPhase
当返回结果的分片数等于预期的总分片数时,协调节点会进入当前Phase的结束处理,启动下一个阶段Fetch Phase的执行。onPhaseDone()会executeNextPhase来执行下一个阶段。
当触发了executeNextPhase方法将触发fetch阶段
上一步的executeNextPhase方法触发Fetch阶段,Fetch阶段的起点为FetchSearchPhase#innerRun函数,从查询阶段的shard列表中遍历,跳过查询结果为空的 shard。其中也会封装一些分页信息的数据。
使用了countDown多线程工具,fetchResults存储某个分片的结果,每收到一个shard的数据就countDoun一下,当都完毕后,触发finishPhase。接着会进行下一步:
CountedCollector:
finishPhase:
执行字段折叠功能,有兴趣可以研究下。即ExpandSearchPhase模块。ES 5.3版本以后支持的Field Collapsing查询。通过该类查询可以轻松实现按Field值进行分类,每个分类获取排名前N的文档。如在菜单行为日志中按菜单名称(用户管理、角色管理等)分类,获取每个菜单排名点击数前十的员工。用户也可以按Field进行Aggregation实现类似功能,但Field Collapsing会更易用、高效。
ExpandSearchPhase执行完了,就返回给客户端结果了。
处理数据节点请求的线程池为:search
根据前面的两个阶段,数据节点主要处理协调节点的两类请求:query和fetch
这里响应的请求就是第一阶段的query请求
executeQueryPhase:
executeQueryPhase会执行loadOrExecuteQueryPhase方法
这里判断是否从缓存查询,默认启用缓存,缓存的算法默认为LRU,即删除最近最少使用的数据。如果不启用缓存则会执行queryPhase.execute(context);底层调用lucene进行检索,并且进行聚合。
关键点:
ElasticSearch查询分为两类,一类为GET,另一类为SEARCH。它们使用场景不同。
本文主要分析了ElasticSearch分布式查询主体流程,并未对lucene部分进行分析,有兴趣的可以自行查找相关资料。
如何查看elasticsearch版本
1、一般情况下如果es服务正常启动,可以通过接口的方式获取elasticsearch版本信息:
curl
上述命令可以得到elasticsearch的服务状态和其他信息包括版本号。
2、如果elasticsearch没有启动,则可以直接找到es的lib包来确认版本号,使用以下命令
ll?lib?|?grep?'elasticsearch-\d\.\d\.\d\.jar'
可以得到如elasticsearch-1.7.4.jar类似的结果,1.7.4即为其版本号。
扩展资料
Elasticsearch的优点介绍:
Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
Elasticsearch是分布式的,这意味着索引可以被分成分片,每个分片可以有0个或多个副本。每个节点托管一个或多个分片,并充当协调器将操作委托给正确的分片。再平衡和路由是自动完成的。
Elasticsearch使用Lucene,它支持facetting和percolating,如果新文档与注册查询匹配,这对于通知非常有用。另一个特性称为“网关”,处理索引的长期持久性;例如,在服务器崩溃的情况下,可以从网关恢复索引。
参考资料:百度百科-elasticsearch
Elasticsearch基础概念之查询流程
查询流程总体可以分为以下几个部分
对于客户端发过来的search请求,最终会在RestSearchAction#prepareRequest方法中处理
经过层层封装,会调用NodeClient#executeLocally方法
之后会执行TransportAction#execute方法
最后会调用TransportSearchAction#doExecute方法
TransportSearchAction#doExecute方法
执行executeSearch方法
执行搜索方法searchAsyncAction(...).start()
这里只分析QUERY_THEN_FETCH这个type类型,最终会调用InitialSearchPhase的run方法,该方法会执行每一个shard请求
调用performPhaseOnShard方法执行shard请求
会调用TransportInterceptor#sendRequest方法发送请求
调用onShardResult收集成功结果
onShardSuccess对所有结果进行收集
successfulShardExecution是否所有请求都已收到回复,都收到之后进行下一阶段
onPhaseDone()会调用AbstractSearchAsyncAction#executeNextPhase方法
FetchSearchPhase继承了SearchPhase类,所以最终会调用FetchSearchPhase#run方法
innerRun()方法
executeFetch方法会处理成功或失败的请求,executeFetch的参数querySearchResult中包含分页信息,最后定义一个Listener,每成功获取一个shard数据后就执行counter.onResult,调用对结果的处理回调,把result保存到数组中,然后执行countDown
onResult方法
当所有shard数据收集完毕后,countDown会执行finishPhase,最终会触发ExpandSearchPhase
取回所有数据之后,执行ExpandSearchPhase#方法
通过sendResponsePhase方法返回给客户端
对于所有的Query和Fetch过程的入口函数在SearchTransportService#registerRequestHandler
查询入口函数是searchService.executeQueryPhase,查询是会优先差是否有缓存,如果有缓存,就查缓存
loadOrExecuteQueryPhase有缓存从缓存加载数据,判断index.requests.cache.enable是否为true(默认为true),来判断是否有缓存。这个cache由节点的所有分片共享,空间满的时候删除最近最少使用的数据,cache并不缓存全部搜索结果
queryPhase.execute查询方法
慢操作Query日志的统计时间在于本阶段的处理时间