elk笔记13--Query DSL

2023-10-27

1 基础介绍

ES 提供了一个丰富的查询DSL(领域特有语言),该语言基于json来定义各种请求。把查询DSL看作为查询的抽象树(AST), 其包含两类使用条款|形式。

第一类:叶子查询子句,该子句在特定的字段中查找特定的值,例如match、term、range查询都属于这一类。这些查询可以被它们自己使用。

第二类:混合查询子句,该子句包含其它叶子查询或混合查询,被用于结合在一个逻辑使用样式(例如bool或者dis_max查询)中的多个查询,也可以用于修改查询的一些行为(例如constant_score query)。

基于查询是否在查询上下文或过滤上下文,查询子句表现会有所不同。

2 常见查询类型

2.1 Query and filter context

  • 相关度分数(Relevance scores)

    默认情况下,es 通过相关度分数对匹配的查询结果进行排序。相关度分数用于测量每个文档和查询的匹配程度。

    相关度分数是一个正浮点数字,它在查询API的返回数据原字段为_score. 通常情况下,_score 越高,文档的相关度越高。es 中每个查询类型会计算出不同的相关度分数,相关度分数计算方式也取决于查询子句是否在请求上下文或者过滤上下文中进行。

  • 查询上下文(Query context)

    在一个查询上下文中,查询子句回答了"特定文档和查询子句匹配程"的问题。除了计算文档是否匹配,查询语句也计算了一个相关度分数,该值存在原字段的_score 中。
    不论何时,只要一个查询子句被传递到一个查询参数中,查询上下文就会其作用,例如查询参数在查询API中。

  • 过滤上下文(Filter context)

    在一个过滤上下文中,查询子句回答了“文档是否匹配查询子句”的问题,其答案是一个简单的是或否,该方式中不计算相关度分数。过滤上线问最多被用于过滤结构数据中,例如:某个时间戳是否在2015-2016之间?字段status是否设置为 published?
    es 为了加速其性能,会将频繁使用的过滤自动缓存起来。
    不论何时,当一个查询子句被传递到一个过滤参数中时,过滤上下文将会起作用。例如:bool 查询中的filter或者must_not参数,constant_score 查询中的过滤参数,或者过滤聚合。

2.2 Compound queries

复合查询包裹着其它复合查询或叶子查询,它要么结合其它查询的结果和相关度分数,以改变它们的行为,要么从查询上下文切换到过滤上下文。

该范畴内的查询包括 bool查询、boosting查询、constant_score查询、dis_max 查询、function_score查询 等5大类,具体如下:

  • bool query
    bool 查询是结合多个叶子查询或者混合查询子句的默认查询,如must、should、must_not 或filter子句。其中,must和should子句有它们自己相关的分数,匹配的子句越多,相关度分数越好;然而,must_not和filter子句在filter上下文中执行,不参与相关度分数计算。
  • boosting query
    boosting查询返回匹配为积极查询的文档,同时减少匹配到为消极查询的文档扽相关度分数。其中,positive 和 negative 为boosting的顶层参数。
  • constant_score query
    constant_score 查询是指:当一个查询包含其它查询,但是在过滤上下文中执行的时候,所有匹配到的文档被赋予一个相同的固定值,默认为1.0。
  • dis_max query
    一个查询可以接受多个查询,并返回任何匹配到查询子句的文档。其中,bool 查询结合多个匹配查询的相关度分数得到一个最终的相关度分数,但dis_max使用单个查询子句中最好的那个查询的相关度分数做为最终的分数。
    例如 bool:[{Query A},{Query B}], 在同时包含A和B的bool查询中,dis_max 返回A 和 B中分值最高的那个做为最终分数。
  • function_score query
    通过一些函数来修改主请求返回的分数,以便于将受欢迎程序、时间、距离或自定义的算法等因素考虑到相关度分数中。

2.3 Full text queries

全文检索允许用户查找被分析器分析的分词字段,例如一个邮件的正文。检索的字符串被之前写入时相同的分析器进行处理。

该范畴内的查询包括 intervals 查询、match 查询、match_bool_prefix 查询、match_phrase 查询、match_phrase_prefix 查询、multi_match 查询、common terms 查询、query_string 查询、simple_query_string 查询等9类,如下所示:

  • intervals query
    intervals 类型的全文检索,可以对匹配项的顺序和距离进行细粒度控制。
  • match query
    match 类型的全文检索是执行全文检索的标准查询方式,包括模糊匹配、词组查询或距离查询。
  • match_bool_prefix query
    match_bool_prefix 查询创建一个bool 查询,该查询匹配每个项为一个term 查询,除了最后一个项,因为最后一项做为一个前缀查询。
  • match_phrase query
    match_phrase 查询像match查询,但是它用于匹配精确的短语或者单词距离匹配。
  • match_phrase_prefix query
    match_phrase_prefix 查询像 match_phrase查询一样,但是它对最后一个单词进行了一个通配符搜索。
  • multi_match query
    multi_match 是match查询的多字段版本。
  • common terms query
    common terms 查询是一个更加特有的查询,该查询给不寻常的词更多偏好(例如 停用词)。
  • query_string query
    query_string 查询支持简洁的Lucene 查询字符串语法,它允许用户在包含单个* 的查询字符串中指定 AND|OR|NOT 条件和多字段搜索。该查询仅仅适用于有经验的用户。
  • simple_query_string query
    simple_query_string 查询是一个更加简单、更加鲁棒的query_string 语法,使用于直接暴露给用户。

2.4 Geo queries

es 支持2类geo数据,分别为geo_point 和geo_shape 2中类型;其中,gep_points 支持 lat/lon 数据对, geo_shape 支持点、线、圆、多边形和多个多边形等。

该范畴内的查询包括 geo_bounding_box查询、geo_distance查询、geo_polygon查询、geo_shape查询等4种,具体如下:

  • geo_bounding_box query
    geo_bounding_box 查询会匹配到在指定矩形区域内的文档。
  • geo_distance query
    geo_distance 查询会匹配到距某个中心点小于某个值的所有文档。
  • geo_polygon query
    geo_polygon 查询会匹配到在指定多边形内的所有文档。
  • geo_shape query
    geo_shape 查询会找到和指定geo-shape 要么相交被包含,要么不相交的文档。

具体案例见elk笔记13–Queries-geo queries

2.5 Joining queries

在像 ES 这样的分布式系统中执行全 SQL 风格的连接查询,其代价昂贵,是不可行的。作为代替,为了实现水平扩展,ES 提供了两种形式的 join。

  • nested query(嵌套查询)
    ES 文档中可能包含嵌套类型的字段,这些字段用来索引一些数组对象,每个对象都可以作为一条独立的文档被查询出来(用嵌套查询)。
  • has_child and has_parent queries
    一类父子关系可以存在单个的索引的两个类型的文档之间。
    join字段关系可以存在于单个索引的文档中。其中,has_child 查询将返回其子文档能匹配特定的查询的父文档,而 has_parent 则返回其父文档能匹配特定查询的子文档。

参考 term 查询中的terms-lookup 机制,它允许用户在另一个文档的值中创建一个term 查询。

2.6 Match all query

Match all 查询是最简单的查询,它匹配所有的文档,并给它们一个相同的相关度分数1.0;其score可以通过boost参数来调整。

GET index_name/_search
{
    "query": {
        "match_all": {}
    }
}

与之相反,Match None 请求不会匹配任何文档,其关键词为 match_none。

2.7 Span queries

Span查询是低级位置查询,可以对指定数据项的顺序和距离提供专业的控制。这些通常用于对法律文件或专利执行非常具体的查询。这些查询通常被用于试试非常特殊的查询,一般用于法律文档或者专利相关的搜索。

It is only allowed to set boost on an outer span query. Compound span queries, like span_near, only use the list of matching spans of inner span queries in order to find their own spans, which they then use to produce a score. Scores are never computed on inner span queries, which is the reason why boosts are not allowed: they only influence the way scores are computed, not spans. [不太很理解Span 查询使用场景,暂时不翻译]

除了 span_multi 查询外, span 查询不能和其它non-span类型的查询混合使用。

该范畴内的查询包括如下9种查询:

  • span_containing query
    Accepts a list of span queries, but only returns those spans which also match a second span query.
  • field_masking_span query
    Allows queries like span-near or span-or across different fields.
  • span_first query
    Accepts another span query whose matches must appear within the first N positions of the field.
  • span_multi query
    Wraps a term, range, prefix, wildcard, regexp, or fuzzy query.
  • span_near query
    Accepts multiple span queries whose matches must be within the specified distance of each other, and possibly in the same order.
  • span_not query
    Wraps another span query, and excludes any documents which match that query.
  • span_or query
    Combines multiple span queries — returns documents which match any of the specified queries.
  • span_term query
    The equivalent of the term query but for use with other span queries.
  • span_within query
    The result from a single span query is returned as long is its span falls within the spans returned by a list of other span queries.

2.8 Specialized queries

Specialized 类别的查询使一些专业的查询,不适合放到其它了查询类别中,当前包括如下7类:

  • distance_feature query
    distance_feature 查询可以根据文档字段和origin之间的距离计算相关度分数,其字段仅仅对 date, date_nanos 和 geo_point 三种类型有效。该查询可以跳过non-competitive的文档,即track_total_hits为false的时候,很多不必要的文档的score不会通过该方式计算。
  • more_like_this query
    more_like_this 查询可以找到和指定的文本、文档或者集合相似的文档。
  • percolate query
    This query finds queries that are stored as documents that match with the specified document.(不太好理解,后续再补上)
  • rank_feature query
    rank_feature 查询可以基于文档的数字特征值来计算相关度分数,并且可以高效地避免 non-competitive 的文档。
  • script query
    script 查询允许通过脚本来实现一个过滤,它一般使用在过滤上下文环境中。
  • script_score query
    script_score 查询允许通过一个脚本来修改子查询的相关度分数。
  • wrapper query
    wrapper 查询可以接受其它json或者yaml字符串类型的请求,其请求体以base64的形式传给warpper的query参数。

2.9 Term-level queries

基于结构化数据中准确的值,用户可以使用term级别的查询来搜索文档。常见结构化数据包括日期范围、IP地址、价格、产品IDs等。

与全文检索不同,项级别的查询不分析查找的项,它会匹配存储在某个字段中的具体项。

term 级别的查询仍然要通过正规化属性将keyword类型的字段项标准化,更多相关细节可以参考 normalizer

term 级别的查询包括如下11 种查询:

  • exists query
    exists 查询用于判断指定字段是否包含写入的值 (写入的值不包含null 和[] ), 若该字段有值则返回对应的文档。
  • fuzzy query
    fuzzy查询指的是搜索出与特定字段的搜索项相似的文档。ES 使用 Levenshtein 编辑距离来测量相似性或模糊性。
    ecommerce中没有mery用户,但是有mary用户,通过fuzzy即可将其查询出来。
    GET kibana_sample_data_ecommerce/_search
    {
    "query": {
      "fuzzy": {
        "user": {
          "value": "mery"
        }
      }
    },
    "_source": "user"
    }
    
  • ids query
    ids 查询基于文档的IDs返回指定的文档。
  • prefix query
    prefix 查询指的是特定的字段包含某个指定的前缀。
  • range query
    range 查询指的是特定字段在某个指定范围内,常见范围包括年龄和分数范围。
  • regexp query
    regexp 查询指的是特定字段匹配到指定的正则表达。
  • term query
    term 查询指的是匹配到指定字段中包含精确的数据项。
  • terms query
    terms 查询指的是匹配到指定字段中某一个精确的数据项。
  • terms_set query
    terms_set 查询指的是在特定字段中匹配到至少某个数量的精确数据项。用户可以通过字段或者脚本定义最少的匹配项。
  • type query
    type 查询返回指定类型的文档。
  • wildcard query
    wildcard 查询返回匹配通配符模式的文档。通配符一般都简单的通配符,例如 ki*y 匹配 以ki开头y结尾 的数据项。

2.10 minimum_should_match parameter

minimum_should_match 该参数定义的是最少应该匹配到的查询子句数量。其值最小为1,最大为实际所有查询子句数量;可以为正整数、负整数、正百分比、负百分比或者整数与百分比的组合,例如[ 3, -3, 75%,-25%, 3<95%,2<-25% 9<-3],最后一个如果为多个的组合则需要在组合之间添加一个空格。

创建索引,设置mappping
PUT test
{
  "mappings": {
    "properties": {
      "aa": {
        "type": "text"
      },
      "bb": {
        "type": "text"
      },
      "cc": {
        "type": "text"
      },
      "dd": {
        "type": "text"
      }
    }
  }
}
写入数据
PUT test/_bulk?refresh
{"index":{"_id":1}}
{"aa":"aa"}
{"index":{"_id":2}}
{"aa":"aa","bb":"bb"}
{"index":{"_id":3}}
{"aa":"aa","bb":"bb","cc":"cc"}
{"index":{"_id":4}}
{"aa":"aa","bb":"bb","cc":"cc","dd":"dd"}
测试
GET test/_search
{
  "query": {
    "bool": {
      "should": [
        {"term": {"aa": {"value": "aa"}}},
        {"term": {"bb": {"value": "bb"}}},
        {"term": {"cc": {"value": "cc"}}},
        {"term": {"dd": {"value": "dd"}}}
      ],
      "minimum_should_match": "-25%"
    }
  }
}
当前值为-25%,即要匹配到3个,因此_id为3 4 的两个都可以匹配到;
当值为2的时候,至少需要匹配到2个,因此_id为2 3 4 的三个都可以匹配到;

2.11 rewrite parameter

rewrite 参数适用于有经验的用户来使用,更改这个值可以影响搜索性能和相关性。
ES 在内部使用Apache Lucene来实现写入和搜索,其原始形式是不能执行如下5中查询的:fuzzy、prefix、query_string、regexp、wildcard。
为了能执行这几类查询,Lucene 将这几种查询更改为更简单的形式,例如bool查询、bit 集合。

rewrite 参数决定来如下3个内容:
对于匹配到的每个文档,Lucene 如何计算其相关度分数;
Lucene 是否改变原始查询为bool查询或者bit 集合;
如果改变为bool查询,将包含哪些 term 查询子句。

rewrite常用的值包含如下几个:
constant_score(默认的rewrite值)
constant_score_boolean
scoring_boolean
top_terms_blended_freqs_N
top_terms_boost_N
top_terms_N

使用rewrite参数的时候,一般需要考虑其性能。大多数情况下,推荐使用 constant_score, constant_score_boolean, or top_terms_boost_N 这几种rewrite方法。
其它方法计算相关度分数时,计算代价比较昂贵,并且不能提高查询结果。

2.12 Regular expression syntax

正则表达通过占位符(运算符)在数据中进行模式匹配。它可以判断字符串中是否包含某个字串,也可以实现字串的替换,或者提取出符合条件的字串。

在ES 中,regexp 和 query_string 2种查询支持正则表达。ES 使用 Apache Lucene 的正则表达引擎来解析这些查询。

Lucene 的正则表达引擎支持所有的Unicode 字符,但是实际中值保留了如下几个操作符:
. ? + * | { } [ ] ( ) " \
若启用选择性操作符,如下几个字符也可以在正则中使用:
# @ & < > \ ~

Lucene 的正则表达引擎不支持锚操作符(anchor operators), 例如不支持 ^ (beginning of line) 和 $ (end of line。 若要匹配一个项,正则表达必须匹配完整的字符串。

regexp-syntax

3 常见查询案例

待添加

4 注意事项

es 默认返回的hits为10000个,如果需要返回全部的,则需要设置如下参数为true; “track_total_hits”: true, 也可以使用scroll api 获取所有的数据;

5 说明

  1. 参考文档
    compound-queries
    elasticsearch 高手之路
  2. 环境说明
    测试环境为es7.2.1
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

elk笔记13--Query DSL 的相关文章

  • 了解elasticsearch如何在内部存储日期

    我想了解 ES 如何在其索引内部存储日期值 它会转换为 UTC 吗 我有一个日期类型的字段 t 这是映射 t type date 现在 当我向 ES 插入 添加文档时 它如何存储在索引中 t 1427700477165 从 Date now
  • 作用域对象的 Xtext 示例

    我正在寻找一个示例 在 XText 中 说明如何在用户定义的对象成员上实现代码完成 据我所知 我需要使用 IScope 但所有这些如何连接在一起还不清楚 鉴于trait是用户定义的类型 我如何构建语法来编码完成 验证其中包含的方法Strin
  • 如何在logstash.conf文件中创建多个索引?

    我使用以下代码在logstash conf中创建索引 output stdout codec gt rubydebug elasticsearch host gt localhost protocol gt http index gt tr
  • 如何使用elasticsearch进行分页?来自 vs 滚动 API

    我使用elasticsearch作为数据库来存储大量日志数据 我知道有两种方法可以进行分页 使用大小并来自 API 使用滚动API 现在我使用 from 进行分页 从前端和后端获取页面和大小参数 Java searchSourceBuild
  • Spark parquet 分区:大量文件

    我正在尝试利用 Spark 分区 我试图做类似的事情 data write partitionBy key parquet location 这里的问题是每个分区都会创建大量镶木地板文件 如果我尝试从根目录读取 则会导致读取速度变慢 为了避
  • 如何让 Kotlin 类型安全构建器在 Scala 中工作?

    Kotlin 很棒类型安全的构建者 https kotlinlang org docs reference type safe builders html这使得创建像这样的 dsl 成为可能 html head title The titl
  • Elasticsearch:如何查询连接数?

    如何询问我的 Elasticsearch 服务器现在有多少个连接 这与插座数量相同吗 我也不知道如何获得这些数字 这与客户端的数量不同 对吧 因为每个客户端可能打开多个连接 找不到任何相关信息 但我确实发现您可以在 Elasticsearc
  • 局部敏感哈希 - Elasticsearch

    有没有允许在 Elasticsearch 上使用 LSH 的插件 如果是的话 您能否指出该位置并告诉我如何使用它 谢谢 编辑 我发现ES使用了MinHash插件 我怎样才能用这个来比较文件呢 查找重复项的最佳设置是什么 有一个Elastic
  • 如何使用 django-haystack 和 elasticsearch 后端进行模糊搜索?

    看起来好像elasticsearch支持模糊查询 http www elasticsearch org guide reference query dsl fuzzy query http www elasticsearch org gui
  • 特定领域语言与函数库

    这可能是主观的 我不知道 我有这个问题 我有点等同于 这个项目用什么语言 问题 因为我似乎无法解决它 我受委托为一个非常精通技术的社区 但不是程序员 写一本关于某个领域 比如说物理学的一个非常具体的分支 的书 这是一本关于他们日复一日使用的
  • 如何在不更改设置的情况下不区分大小写排序

    我的索引名称是 data new 下面是插入索引的代码 test id 1 name A professor Bill Cage accounting id 2 name AB professor Gregg Payne engineeri
  • ElasticSearch - 仅获取与搜索响应中所有顶级字段匹配的嵌套对象

    假设我有以下文档 id 1 name xyz users name abc surname def name xyz surname wef name defg surname pqr 我只想获取与搜索响应中的所有顶级字段匹配的嵌套对象 我
  • 弹性搜索文档计数

    我正在运行 2 2 版本的 Elastic 搜索 我已经创建了索引并加载了示例文档 我发现其中有些问题 当我给予 GET index type count 我得到了正确的答案 count 9998 shards total 5 succes
  • 无法使用docker在Apple Mac芯片M1上启动elasticsearch

    在发布这个问题之前 我浏览了许多链接 例如 Kibana 无法在 Mac M1 上使用 docker 连接到 ElasticSearch https stackoverflow com questions 73160632 kibana c
  • Nest Elastic - 构建动态嵌套查询

    我必须使用 Nest 查询嵌套对象 但是查询是以动态方式构建的 下面的代码演示了以静态方式对嵌套 书籍 进行查询 QueryContainer qry qry new QueryStringQuery DefaultField name D
  • search_after 在弹性搜索中如何工作?

    我一直在尝试在我们的应用程序中使用 Elasticsearch 但分页限制为 10k 对我们来说实际上是一个问题 并且由于必须超时问题 滚动 API 也不是推荐的选择 我发现 Elasticsearch 有一个叫做 search after
  • jq Streaming - 过滤嵌套列表并保留全局结构

    在一个大型 json 文件中 我想从嵌套列表中删除一些元素 但保留文档的整体结构 我的示例将其输入为 但真实的输入足够大以要求流式传输 keep untouched keep this this list filter this keep
  • 即使禁用安全性,OAuth 令牌 API 也无法在 Elastic Search 中工作

    我是 Elastic search 新手 使用 Elastic search 版本 7 7 1 我想通过以下方式生成 OAuth 令牌弹性搜索文档 https www elastic co guide en elasticsearch re
  • Elastic Search 索引经常被删除[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在 google cloud 上对个人项目运行弹性搜索 并将其用作我的应用程序的搜索索引 从最近三天开始 索引就被神秘地删除了 我不知
  • AWS ElasticSearch Service - 从 CF 模板设置加密选项

    我正在创建一个云形成模板来在AWS中配置elasticsearch服务域 我想将加密下的此属性设置为 true 域的所有流量都需要 HTTPS 但我无法在 AWS 文档中找到执行此操作的方法 用于设置加密属性的其他选项 例如 启用静态数据加

随机推荐