在 Elasticsearch 中,提供了功能十分丰富、多种表现形式的查询语言—— DSL 查询。
DSL 查询使用 JSON 格式的请求体与 Elasticsearch 交互,可以实现各种各样的查询需求。
DSL 查询主要包含两种类型的查询语句:
叶子查询语句 : 用于查询特殊字段的特殊值,例如:match, term, range 等。
复合查询语句 : 可以合并其他的叶子查询或复合查询,从而实现非常复杂的查询逻辑。
查询语句的执行结果依赖于它们是用于查询语境还是过滤语境。
基本语法
使用 DSL 查询,需用到 query 参数。
基本的语法格式:
GET /_search { "query": <query clause> }
空查询
没有查询条件的查询,就是空查询。它会匹配所有的文档。
GET /_search { "query": {} }
等同于
GET /_search
等同于
GET /_search { "query": { "match_all": {} } }
基本查询
例如,使用 match 查询 full_name 字段中包含 john 的记录。
GET /_search { "query": { "match": { "full_name": "john" } } }
查询与过滤
DSL 查询根据使用目的的不同分为两种类型:
上下文查询(Query context),简称查询
上下文过滤(Filter context),简称过滤
查询(Query)
在上下文查询语境中,查询语句会询问文档与查询语句的匹配程度,此外,它会判断文档是否匹配并计算相关性评分(_score)的值。
过滤(Filter)
在上下文过滤语境中,查询语句主要解决文档是否匹配的问题,而不会在意匹配程度(相关性评分)。过滤主要用于结构化的数据。
例如:
status 字段的值是否为某个枚举值或布尔值?
age 字段的值是否在 20-35 范围内?
date 字段的值是否在 2016-2019 之间?
一般来说,过滤语句比查询语句的执行效率更高,因为它不用计算文档的相关性评分(score)。
使用频繁的过滤语句的结果集会被 Elasticsearch 自动缓存,以提高性能。
过滤的目的就是粗暴地快速缩小匹配的结果集。
通常,全文搜索或需要用到相关性评分(score)的场景采用查询(query),其他的全部用过滤(filter)。
在进行搜索时,我们常常会在查询语句中,结合查询和过滤来达到我们的查询目的。
下面是一个示例:
GET /_search { "query": { "bool": { "must": [ { "match": { "title": "Search" }}, { "match": { "content": "Elasticsearch" }} ], "filter": [ { "term": { "status": "published" }}, { "range": { "publish_date": { "gte": "2015-01-01" }}} ] } } }
全文查询
全文查询语句通常用于全文本字段的查询。
match
match 查询可操作文本、数值和日期类型的数据,分析它们并构建查询语句。
示例:查询 full_name 字段中包含 John 或 Smith 的文档。
GET /_search { "query" : { "match" : { "full_name" : "John Smith" } } }
说明: Elasticsearch 会先使用分析器分析 "John Smith" 为两个独立的项 "John" 和 "Smith",然后再去构建查询。
这里的 full_name 字段可以替换为任何你想查询的字段甚至是 _all 字段。
match 属于 boolean 的类型,也就是说,分析器会对提供的查询文本进行分析并构建 boolean 查询语句。
由 match 构建的 boolean 查询语句默认是逻辑或(or),当然,我们可以通过 operator 参数来改变这个默认行为。
示例:查询 full_name 字段中包含 John 和 Smith 的文档。
GET /_search { "query": { "match" : { "full_name" : { "query" : "John Smith", "operator" : "and" } } } }
说明: full_name 是字段名称,query 参数的值是提供的查询文本,operator 参数用于设置 match 的逻辑(or 还是 and)。
match_phrase
match_phrase,即短语(词组)匹配,它会分析提供的查询文本并构建一个 phrase 查询。
match_phrase 用于精准的 phase 匹配。
示例:查询 full_name 字段中包含 "John Smith" 短语的文档。
GET /_search { "query" : { "match_phrase" : { "full_name" : "John Smith" } } }
我们也可以给提供的查询文本指定 analyzer(分析器),如果没有指定,默认使用字段的显式 mapping 中的定义,或者默认的 search analyzer。
GET /_search { "query": { "match_phrase" : { "full_name" : { "query" : "John Smith", "analyzer" : "standard" } } } }
match_phrase_prefix
match_phrase_prefix 和 match_phrase 类似,但 match_phrase_prefix 不是精准匹配,而是前缀匹配,它会对查询文本的最后一个字符后的内容进行通配符搜索。
示例:查询 full_name 字段中以 "John Smi" 短语开头的文档。
GET /_search { "query" : { "match_phrase_prefix" : { "full_name" : "John Smi" } } }
multi_match
multi_match 用于多字段匹配查询。
GET /_search { "query" : { "multi_match": { "query": "John Smith", "fields": ["first_name", "full_name"] } } }
Term-level 查询
我们知道,全文查询在执行查询之前,会先对提供的查询文本进行分析。
然而,Term-level 查询是直接查询倒排索引中的确切的值。
Term-level 查询通常用于结构化的数据,如数值、日期、枚举值或关键字,而不是文本(text)。
term
term 用于查询指定字段的倒排索引包含某个确切值的记录。
POST /_search { "query": { "term" : { "first_name" : "john" } } }
terms
terms 和 term 类似,只不过提供的确切的值是数组。类似于 MySQL 的 in 条件。
POST /_search { "query": { "terms" : { "full_name" : ["john", "john2"] } } } POST /_search { "query": { "constant_score": { "filter": { "terms" : { "full_name" : ["john", "john2"] }} } } }
range
range 用于范围查询。
GET /_search { "query": { "range" : { "info.age" : { "gte" : 28, "lt" : 60, "boost" : 2.0 } } } }
说明: boost 参数可用于调整相关性评分(score)的值。
GET /_search { "query": { "range" : { "date" : { "gt" : "now-3d/d", "lt" : "now" } } } }
exists
exists 返回字段值不为 null 的记录。
GET /_search { "query": { "exists" : { "field" : "user" } } }
prefix
prefix 返回字段的 term 以确切的前缀(前缀不会被分析)开头的记录。
GET /_search { "query": { "prefix" : { "full_name" : "joh" } } }
wildcard
wildcard 指的是通配符查询。
支持的通配符主要有:
* 匹配 0 个或多个任意字符
? 匹配 1 个任意字符
GET /_search { "query": { "wildcard" : { "full_name" : "john*" } } }
regexp
regexp 指的是正则查询。
GET /_search { "query": { "regexp" : { "full_name" : "jo.*" } } }
fuzzy
fuzzy 指的是容差查询,即可以容忍确切的值和倒排索引中的 term 之间有误差。
GET /_search { "query": { "fuzzy" : { "full_name" : "joh" } } } GET /_search { "query": { "fuzzy" : { "full_name" : { "value" : "joh", "fuzziness" : 2, "prefix_length" : 0, "max_expansions": 100 } } } }
type
type 查询指的是根据文档的 type 来查询。
这里的 type 就是文档的类别(逻辑分组),类似于 MySQL 的数据表。
GET /_search { "query": { "type" : { "value" : "user" } } }
ids
ids 查询指的是根据文档的 id 来查询。
GET _search { "query": { "ids" : { "values" : ["1", "2", "60"] } } }
复合查询
constant_score
constant_score 复合查询只会在过滤上下文中执行查询语句,并且返回的所有的记录的 _score 值是一个常量。
GET /_search { "query": { "constant_score" : { "filter" : { "term" : { "full_name" : "john"} }, "boost" : 1.5 } } }
<360>
bool
bool 复合查询用于组合叶子查询语句或复合查询语句。如:must, should, must_not, or filter。
must 必须匹配。
should 至少匹配一个文档。
filter 必须匹配,忽略相关性评分。
must_not 必须不匹配,忽略相关性评分。
说明: must 和 should 在查询上下文中执行;must_not 和 filter 在过滤上下文中执行。
POST /_search { "query": { "bool" : { "must" : { "term" : { "last_name" : "smith" } }, "filter": { "term" : { "info.interests" : "musics" } }, "must_not" : { "range" : { "info.age" : { "gte" : 10, "lte" : 25 } } }, "should" : [ { "term" : { "full_name" : "john" } }, { "term" : { "full_name" : "smith" } } ], "minimum_should_match" : 1, "boost" : 2.0 } } }
发表评论 取消回复