elasticsearch查询,elasticsearch查询语句

http://www.itjxue.com  2023-01-06 18:14  来源:未知  点击次数: 

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日志的统计时间在于本阶段的处理时间

(责任编辑:IT教学网)

更多

推荐时间特效文章