Elasticsearch DSL 查询详解
在 Elasticsearch 中,提供了功能十分丰富、多种表现形式的查询语言—— DSL 查询。
DSL 查询使用 JSON 格式的请求体与 Elasticsearch 交互,可以实现各种各样的查询需求。
DSL 查询主要包含两种类型的查询语句:
叶子查询语句 : 用于查询特殊字段的特殊值,例如:match, term, range 等。
复合查询语句 : 可以合并其他的叶子查询或复合查询,从而实现非常复杂的查询逻辑。
查询语句的执行结果依赖于它们是用于查询语境还是过滤语境。
基本语法
使用 DSL 查询,需用到 query 参数。
基本的语法格式:
GET /_search
{
“query”:
}
空查询
没有查询条件的查询,就是空查询。它会匹配所有的文档。
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
}
}
}
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
}
}
}
参考文献
[1] https://www.elastic.co/guide/en/elasticsearch/reference/5.2/index.html
————————————————
版权声明:本文为CSDN博主「lamp_yang_3533」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lamp\_yang\_3533/article/details/97618687
还没有评论,来说两句吧...