【Elasticsearch】学好Elasticsearch系列-Query DSL 1

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 【Elasticsearch】学好Elasticsearch系列-Query DSL

先看后赞,养成习惯。

点赞收藏,人生辉煌。

DSL是Domain Specific Language的缩写,指的是为特定问题领域设计的计算机语言。这种语言专注于某特定领域的问题解决,因而比通用编程语言更有效率。

在Elasticsearch(ES)中,DSL指的是Elasticsearch Query DSL,一种以JSON形式表示的查询语言。通过这种语言,用户可以构建复杂的查询、排序和过滤数据等操作。这些查询可以是全文搜索、分面/聚合搜索,也可以是结构化的搜索。

查询上下文

使用query关键字进行检索,倾向于相关度搜索,故需要计算评分。搜索是Elasticsearch最关键和重要的部分。

在查询上下文中,一个查询语句表示一个文档和查询语句的匹配程度。无论文档匹配与否,查询语句总能计算出一个相关性分数在_score字段上。

相关度评分:_score

相关度评分用于对搜索结果排序,评分越高则认为其结果和搜索的预期值相关度越高,即越符合搜索预期值,默认情况下评分越高,则结果越靠前。在7.x之前相关度评分默认使用TF/IDF算法计算而来,7.x之后默认为BM25。

源数据:_source

source字段包含索引时原始的JSON文档内容,字段本身不建立索引(因此无法进行搜索),但是会被存储,所以当执行获取请求是可以返回source字段。

虽然很方便,但是source字段的确会对索引产生存储开销,因此可以禁用source字段,达到节省存储开销的目的。可以通过以下接口进行关闭。

PUT my_index
{
  "mappings": {
    "_source": {
      "enabled": false
    }
  }
}

但是需要注意的是这么做会带来一些弊端,_source禁用会导致如下功能无法使用:

  • 不支持update、update_by_query和reindex API。
  • 不支持高亮。
  • 不支持reindex、更改mapping分析器和版本升级。

总结:在禁用source之前,应该仔细考虑是否需要进行此操作。如果只是希望降低存储的开销,可以压缩索引比禁用source更好。

数据源过滤器

例如,假设你的应用只需要获取部分字段(如"name"和"price"),而其他字段(如"desc"和"tags")不经常使用或者数据量较大,导致传输和处理这些额外的数据会增加网络开销和处理时间。在这种情况下,通过设置includes和excludes可以有效地减少每次请求返回的数据量,提高效率。例如:

PUT product
{
  "mappings": {
    "_source": {
      "includes": ["name", "price"],
      "excludes": ["desc", "tags"]
    }
  }
}

Including:结果中返回哪些field。

Excluding:结果中不要返回哪些field,不返回的field不代表不能通过该字段进行检索,因为元数据不存在不代表索引不存在,Excluding优先级比Including更高。

需要注意的是,尽管这些设置会影响搜索结果中_source字段的内容,但并不会改变实际存储在Elasticsearch中的数据。也就是说,"desc"和"tags"字段仍然会被索引和存储,只是在获取源数据时不会被返回。

在mapping中定义这种方式不推荐,因为mapping不可变。我们可以在查询过程中使用_source指定返回的字段,如下:

GET product/_search
{
  "_source": {
    "includes": ["owner.*", "name"],
    "excludes": ["name", "desc", "price"]
  },
  "query": {
    "match_all": {}
  }
}

Elasticsearch的_source字段在查询时支持使用通配符(wildcards)来包含或排除特定字段。使得能够更灵活地操纵返回的数据。

关于规则,可以参考以下几点:

  • *:匹配任意字符序列,包括空序列。
  • ?:匹配任意单个字符。
  • [abc]: 匹配方括号内列出的任意单个字符。例如,[abc]将匹配"a", "b", 或 "c"。

请注意,通配符表达式可能会导致查询性能下降,特别是在大型索引中,因此应谨慎使用。

全文检索

全文检索是Elasticsearch的核心功能之一,它可以高效地在大量文本数据中寻找特定关键词。

在Elasticsearch中,全文检索主要依靠两个步骤:"分析"(Analysis)和"查询"(Search)。

  1. 分析: 当你向Elasticsearch索引一个文档时,会进行"分析"处理,将原始文本数据转换成称为"tokens"或"terms"的小片段。这个过程可能包括如下操作:
  • 切分文本(Tokenization)
  • 将所有字符转换为小写(Lowercasing)
  • 删除常见但无重要含义的单词(Stopwords)
  • 提取词根(Stemming)
  1. 查询: 当执行全文搜索时,查询字符串也会经过类似的分析过程,然后再与已经分析过的索引进行比对,找出匹配的结果并返回。

Elasticsearch提供了许多种全文搜索的查询类型,例如:

  • Match Query: 最基本的全文搜索查询。
  • Match Phrase Query: 用于查找包含特定短语的文档。
  • Multi-Match Query: 类似Match Query,但可以在多个字段上进行搜索。
  • Query String Query: 提供了丰富的搜索语法,可以执行复杂的、灵活的全文搜索。

match:匹配包含某个term的子句

GET product/_search
{
  "query": {
    "match": {
      "name": "xiaomi nfc phone"
    }
  }
}

上面的搜索语句,只要文档的"name"字段包含"xiaomi"、"nfc"或者"phone"中的任何一个词,就会被视为匹配。

match_all:匹配所有结果的子句

match_all 是 Elasticsearch 中的一个查询类型,它匹配所有文档,不需要任何参数。

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

上面的语句等价于:

GET /product/_search

这个查询将会返回索引中的所有文档。这通常用于在没有特定搜索条件时获取所有的文档,或者与其他查询结合使用(如过滤器)。

需要注意,由于 match_all 查询可能返回大量的数据,所以一般在使用时都会与分页(pagination)功能结合起来,这样可以控制返回结果的数量,避免一次性加载过多数据导致的性能问题。例如,你可以使用 fromsize 参数来限制返回结果:

GET /_search
{
  "query": {
    "match_all": {}
  },
  "from": 10,
  "size": 10
}

multi_match:多字段条件

multi_match 查询是 Elasticsearch 中用来在多个字段上执行全文查询的功能。它接受一个查询字符串和一组需要在其中执行查询的字段列表。例如:

GET /_search
{
  "query": {
    "multi_match" : {
      "query":  "xiaomi nfc phone", 
      "fields": [ "name", "description" ] 
      }
  }
}`

这个查询会在 "name" 和 "description" 两个字段中查找包含 "xiaomi nfc phone" 的文档。

multi_match 还支持多种类型的匹配模式,如:best_fields, most_fields, cross_fields, phrase, phrase_prefix等。这些类型的行为略有不同,可以按照实际需求进行选择。

例如,“best_fields” 类型会从指定的字段中挑选分数最高的匹配结果计算最终得分,而“most_fields” 类型则会在每个字段中都寻找匹配项并将其分数累加起来。

需要注意的是,当使用 multi_match 查询时,如果字段不同,其权重可能也会不同。你可以通过在字段名后面添加尖括号(^)和权重值来调整特定字段的权重。例如,"fields": [ "name^3", "description" ]表示在"name"字段中的匹配结果权重是"description"字段的三倍。

match_phrase:短语查询

match_phrase 是 Elasticsearch 中的一种全文查询类型,它用于精确匹配包含指定短语的文档。match_phrase 查询需要字段值中的单词顺序与查询字符串中的单词顺序完全一致。

例如:

GET /_search
{
  "query": {
    "match_phrase": {
      "message": "this is a test"
    }
  }
}

这个查询将会找到"message"字段中包含完整短语"this is a test"的所有文档。

此外,match_phrase 查询还有一个 slop 参数,可以定义词组中的词语可能存在的位置偏移量。例如,如果将 slop 设置为 1,则查询 "this is a test" 也可匹配 "this is test a",因为 "a" 和 "test" 只需移动一个位置即可匹配。

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
目录
相关文章
|
11月前
|
Web App开发 自然语言处理 API
巧记Elasticsearch常用DSL语法
记知识先记轮廓,关于DSL语法的轮廓,记住以下3句话即可:1.索引、文档和查询。2.Match、Term和Bool。3.还有翻页和聚合
巧记Elasticsearch常用DSL语法
|
2月前
|
存储 数据库 索引
面试题ES问题之动态映射的定义如何解决
面试题ES问题之动态映射的定义如何解决
26 1
|
4月前
|
SQL Java 关系型数据库
spring data elasticsearch 打印sql(DSL)语句
spring data elasticsearch 打印sql(DSL)语句
338 0
|
10月前
|
JSON 自然语言处理 数据格式
分布式系列教程(33) -ElasticSearch DSL语言查询与过滤
分布式系列教程(33) -ElasticSearch DSL语言查询与过滤
175 0
|
4月前
|
自然语言处理 索引
Elasticsearch之常用DSL语句
mapping是对索引库中文档的约束
|
4月前
|
JSON 自然语言处理 算法
【Elasticsearch】DSL查询文档
【Elasticsearch】DSL查询文档
345 0
|
4月前
|
Java 索引
ElasticSearch DSL操作
ElasticSearch DSL操作
97 1
|
4月前
dsl语句查询elasticsearch集群节点分布和资源使用情况
dsl语句查询elasticsearch集群节点分布和资源使用情况
136 0
|
4月前
elasticsearch7.x kibana的常用DSL(自己练习的)
elasticsearch7.x kibana的常用DSL(自己练习的)
|
12月前
|
SQL 关系型数据库 索引
Elasticsearch查询时还在百度DSL语句吗?你可能需要这份总结
Elasticsearch查询时还在百度DSL语句吗?你可能需要这份总结
下一篇
云函数