Elasticsearch查询

Query DSL

Elasticsearch提供了一个基于JSON的完整的查询DSL(领域特定语言)。它定义的查询语言由两种类型的子句组成:“叶子查询子句”和“组合查询子句”。

叶子查询子句

叶子查询子句查找特定字段中的特定值,例如 matchtermrange 查询。

复合查询子句

复合查询子句包装其他叶子或复合查询,并用于以逻辑方式组合多个查询(如 bool 或 dis_max 查询),或更改其行为(如 constant_score 查询)。

1.  Query and filter context

查询子句的行为取决于它是用在查询上下文(query context)还是用在过滤器上下文(filter context):

1.1.  Query context

在查询上下文中的查询子句回答了“这个文档与这个查询子句的匹配程度是怎样的?”问题。除了决定文档是否匹配以外,查询子句还会计算一个“_score”,它表示文档与其他文档的相关程度。

1.2.  Filter context

在过滤器上下文中,一个查询子句回答了“这个文档与查询子句匹配吗?”的问题。这个答案是简单的Yes或者No,也不会计算分数。过滤上下文主要用于过滤结构化数据,例如:

  • 这个timestamp在2015年到2016年的范围内吗?
  • 这个status字段的值是“published”吗?

PS:Query VS Filter

  1. 查询反应的是文档与查询子句的匹配程度,而过滤反应的是文档是否匹配查询子句
  2. 一个是筛选是否满足条件,情况无非两种:是或不是;一个是看满足条件的记录与查询条件的匹配程度
  3. 哪些满足条件,这是过滤;满足条件的这些记录与条件的匹配程度,这是查询
  4. 过滤不会计算评分,查询会计算评分

频繁使用的过滤器将被Elasticsearch自动缓存,以提高性能。

当查询子句中被传递了一个filter参数时过滤器上下文就生效了。例如,bool查询中的filter参数或者must_not参数。

下面是一个查询子句的例子,这个查询将匹配满足以下所有条件的文档:

  • title 字段包含单词“search
  • content 字段包含单词“elasticsearch
  • status 字段包含明确的单词“published
  • publish_date 字段的包含的日期大于或等于2015-01-01
curl -X GET "localhost:9200/_search" -H 'Content-Type: application/json' -d'
{
    query": { 
        bool: { 
            must: [
                { match": { title":   Search        }},{ content": Elasticsearch }}  
            ],filter: [ 
                { term":  { statuspublished }},1)">rangepublish_dategte2015-01-01 }}} 
            ]
        }
    }
}
'

关于上面的查询子句作如下说明:

  1. quary 参数表示这是一个查询上下文
  2. bool 和 两个match子句用在查询上下文中,表明它们参与每条文档的打分
  3. filter 参数表明这是过滤器上下文
  4. termrange 子句用在过滤器上下文中,它们会过滤掉不匹配的文档,而且不会影响匹配文档的分数

(PS:类比SQL的话,match相当于模糊查询,term相当于精确查询,range相当于范围查询)

2.  Match All Query

最简单的查询,匹配所有文档,使它们的_score为1.0

curl -X GET : {
        match_all: {}
    }
}
'

_score可以被改变,通过用boost参数

curl -X GET boost" : 1.2 }
    }
}
'

match_all相反的是match_none,它不匹配任何文档

curl -X GET match_none'

3.  Full text queries

3.1.  Match Query

match查询接受文本/数值/日期类型的数据,分析它们,并构造一个查询。

match是一种布尔类型的查询。这意味着它对提供的文本进行分析,并在分析的过程中为提供的文本构造一个布尔查询。operator 选项可以设置为 or 或者 and 以此来控制布尔子句(默认是 or )。例如:

curl -X GET  : {
            messagethis is a test
        }
    }
}
'

注意,查询语句都是以“query”开头的,这里“message”是字段名

你也可以加一些参数,比如:

curl -X GET  : {
                ,1)">operatorand
            }
        }
    }
}
'

(PS:match是模糊查询)

3.2.  Match Phrase Query

match_phrase 查询与 match类似,但是它是用于精确匹配或单词接近匹配的。例如:

curl -X GET match_phrase'

当然,你也可以加参数

curl -X GET analyzermy_analyzer'

这里“analyzer”是用来设置用那个分析器来分析文本

3.3.  Match Phrase Prefix Query

类似于match_phrase查询,但是对最后一个单词进行通配符搜索。

match_phrase_prefix允许文本的最后一个单词进行前缀匹配

curl -X GET match_phrase_prefixquick brown f'

除了match_phrase允许的那些参数外,match_phrase_prefix还可以接受一个max_expansions参数,它是用来控制最后一个单词可以扩展多少后缀(默认50)。

curl -X GET max_expansions10'

3.4.  Multi Match Query

multi_match 相当于 match 的多字段版本

顾名思义,multi_match可以指定多个字段,而match只能针对一个字段

curl -X GET {
  : {
    multi_match : {
      ":    fields": [ subject", ] 
    }
  }
}
'

另外,字段可以用通配符,例如下面的例子中可以查询 title , first_name , last_name 等字段:

curl -X GET Will Smith*_name'

单个字段可以被提升,例如:

curl -X GET " : [ subject^3'

上面的例子,subject字段的重要性是message字段的三倍

3.5.  Query String Query

支持Lucene查询字符串语法,允许指定 AND | OR | NOT ,并且在单个查询字符串中进行多字段查询

curl -X GET query_stringdefault_fieldthis AND that OR thus'

query_string查询解析输入并围绕操作符拆分文本,每个文本部分都是独立分析的,例如:

curl -X GET (new york city) OR (big apple)'

上面的例子中,将被拆分成 “new york city” 和 “big apple” 两部分,并且每一部分都被分析器独立分析

注意,按操作符拆分

query_string的参数包括:

query  实例被解析的查询文本

default_field  如果没有指定前缀字段的话,这是默认的查询字段。(默认查询所有字段)

default_operator  如果没有明确指定操作符的话,那么这是默认的操作符。例如,如果默认操作符是OR的话,那么“my name is jack”将被翻译成“my OR name OR is OR jack”,同理,如果是AND,则被翻译成“my AND name AND is AND jack”

analyzer  用来解析查询字符串的解析器的名字

allow_leading_wildcard  如果设置了,那么 * 或 ? 允许作为第一个字符。默认是true

lenient  如果设置为true,则格式失败将被忽略

在query_string中,多字段查询应该这样写:

curl -X GET " : [name],1)">this AND that'

等价于

curl -X GET : {
            (content:this OR name:this) AND (content:that OR name:that)'

上面两个是等价的

3.6.  Simple Query String Query

simple_query_string 是query_string的一个更简单、更健壮、更适合面向用户的版本

使用SimpleQueryParser解析上下文的查询。与常规的query_string查询不同,simple_query_string查询永远不会抛出异常,并丢弃查询的无效部分。

curl -X GET simple_query_string : {
        \"fried eggs\" +(eggplant | potato) -frittata": [title^5bodydefault_operator
    }
  }
}
'

3.7.  实例练习

准备数据

//    删除索引
curl -X DELETE 192.168.1.134:9200/book"

    创建索引
curl -X PUT settingsnumber_of_shards1
    },1)">mappings_docproperties":        { typetext  },1)">author":         { introduction: { 
                    dateformatyyyy-MM-dd
                }
            }
        }
    }
}
'

    查看索引
curl -X GET 192.168.1.134:9200/book?pretty    插入文档
curl -X PUT 192.168.1.134:9200/book/_doc/1Hello Javazhangsan2008-11-15This is a book for novice.
}
    查看文档
curl -X GET 192.168.1.134:9200/book/_search?pretty'

 

match查询(注意,match查询只能是针对单个字段)

这个例子中,我们用“Java”查询到2条,接下来用“Java入门”将查到5条

这是因为解析器会将“Java入门”拆分为“Java”和“入门”两个单词,而且默认的操作符是or

也就是说,查询的结果是title中包含“Java”或者“入门”的记录

现在变成查询title中同时包含“Java”和“入门”的记录,因此只有1条

 multi_match多字段查询

 match_phrase查询

对比不难发现,同样的关键字“Java从”,用match查出5条,用match_phrase只查出1条

 

query_string查询

4.  Term level queries(单词级别查询)

全文本查询会在执行之前对查询字符串进行分析,而单词级别查询会对存储在反向索引中的精确的term进行操作。

这些查询通常用于结构化的数据,比如:numbers , dates ,enums 等,而不是对全文本字段。

(PS:也就是说,全文本查询之前要先对文本内容进行分词,而单词级别的查询直接在相应字段的反向索引中精确查找,单词级别的查询一般用于数值、日期等类型的字段上)

4.1.  Term Query

在指定的字段中查找包含指定的精确的term的文档

term查询将在反向索引(或者叫倒排索引)中查找包含特定的精确的term的文档。例如:

curl -X POST " : { userKimchy } 
  }
}
'

上面的例子,在user字段的反向索引中查找包含精确的Kimchy的文档

还可以指定一个boost参数,使这个term查询比另一个查询具有更高的相关性得分。例如:

curl -X GET should: [
            {
                : {
                    : {
                        valueurgent2.0 
                    }
                }
            },{
                normal 
                }
            }
          ]
        }
    }
}
'

这个例子中,urgent查询子句有一个boost参数值为2.0,这就意味着它的重要程度是后面的normal查询子句的两倍,normal子句默认的boost是1.0

4.2.  Terms Query

查找包含指定字段中指定的任何确切term的文档

筛选出与所提供的terms中任何一个匹配的文档

curl -X GET termskimchyelasticsearch]}
    }
}
4.3.  Range Query

查找指定字段在指定范围内包含值(日期、数字或字符串)的文档。

下面的例子返回age字段的值在10到20之间的文档:

curl -X GET agelte20'

range查询可以接受下列参数:

gte  大于或等于

gt    大于

lte   小于或等于

lt     小于

boost  设置boost值,默认是1.0

4.3.1.  Range on date fields

当range查询用于date类型的字段时,范围可以用Date Math表示:

curl -X GET now-1d/dlt" :  now/d'

当使用Date Math将日期四舍五入到最近的日期、月份、小时等时,四舍五入日期取决于范围的两端是包含的还是排除的。

例如:

rounded up 向上舍入

rounded down 向下舍入

gt 大于2014-11-18||/M  变成 2014-11-30T23:59:59.999 

gte 大于或等于2014-11-18||/M  变成 2014-11-01

lt 小于2014-11-18||/M  变成  2014-11-01

lte 小于或等于2014-11-18||/M  变成2014-11-30T23:59:59.999 

这个其实很好理解,

大于2014-11-18||/M相当于是大于2014年11月,因此大于2014-11-18||/M等价于大于2014-11-30 23:59:59

也就是说,大于11月,相当于是大于11月的最后一天,即11-30 23:59:59

同理,大于或等于2014-11-18||/M,相当于大于或等于11月,自然是11月的第一天,即2014-11-01

同理,小于2014-11-18||/M,相当于小于11月,自然是小于11月1日,故而小于2014-11-18||/M等价于小于2014-11-01

同理,小于或等于2014-11-18||/M,等于11月自然是包含11月的,意味着小于11月30日,故而小于或等于2014-11-18||/M等价于小于或等于2014-11-30 23:59:59

4.3.2.  Date format in range query

在日期范围查询的时候,我们可以指定日期格式。例如:

curl -X GET born01/01/20122013dd/MM/yyyy||yyyy'

这个例子是查询在2012-01-01到2013-12-31之间出生的人

下面看时间范围查询

curl -X GET timestamp2015-01-01 00:00:00nowtime_zone+01:004.4.  Exsit Query

在特定的字段中查找非空值的文档

curl -X GET existsfield4.5.  Prefix Query

查找包含带有指定前缀的term的文档

curl -X GET '
{ prefixki }
  }
}
'

可以关联boost

curl -X GET " :  {  } }
  }
}
4.6.  Wildcard Query

支持通配符查询,*表示任意字符,?表示任意单个字符

curl -X GET wildcardki*y'

可以加boost参数

curl -X GET  } }
    }
}
4.7.  Regexp Query

正则表达式查询

curl -X GET regexp:{
            name.firsts.*y4.8.  Ids Query

用_uid字段查询

curl -X GET idsvalues14100]
        }
    }
}
4.9.  实例练习

5.  复合查询

复合查询包装其他复合查询或叶子查询,以组合它们的结果和得分,更改它们的行为,或从查询切换到筛选上下文。

5.1.  固定分数查询

curl -X GET constant_score}
            },1)">'

5.2.  布尔查询

关于should子句,特别要注意:

如果这个布尔查询位于查询上下文,并且有must或者filter子句,那么即使should子句没有匹配任何文档,也没关系
如果是位于过滤器上下文,或者既没有must也没有filter,那么至少有一个should查询必须匹配文档。
这个行为可以通过设置minimum_should_match参数来显式地控制。

举个例子:

curl -X POST  }
            },1)">: {
                tagtechmust_not : {
                    10,1)"> }
                }
            },1)"> : [
                { wow } },1)"> } }
            ],1)">minimum_should_match1.0'

查询user为“kimchy”,并且tag为“tech”,并且age不在10~20之间,并且tag为wow或elasticsearch的文档

filter查询分数默认是0

curl -X GET : {
      : {
          active
        }
      }
    }
  }
}
5.3.  实例练习

 

参考

https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html

 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


文章浏览阅读774次,点赞24次,收藏16次。typescript项目中我们使用typings-for-css-modules-loader来替代css-loader实现css modules。1、typings-for-css-modules-loader加载器介绍 Webpack加载器,用作css-loader的替代产品,可动态生成CSS模块的TypeScript类型这句话是什么意思呢?就是编译时处理css文件...
文章浏览阅读784次。react router redux antd eslint prettier less axios_react+antd+redux+less
文章浏览阅读3.9k次,点赞5次,收藏11次。需要删除.security-7索引文件。把在第1步中的被注释的配置打开。之后就是按照提示输入密码。执行bin目录下的文件。_failed to authenticate user 'elastic' against
文章浏览阅读1.2k次,点赞23次,收藏24次。Centos 8 安装es_centos8 yum elasticsearch
文章浏览阅读3.2k次。设置完之后,数据会⾃动同步到其他节点。修改密码时,将第⼀步配置删除,然后重启。单独使⽤⼀个节点⽣成证书;执⾏设置⽤户名和密码的命令。执⾏完上⾯命令以后就可以在。⽂件,在⾥⾯添加如下内容。这个⽂件复制到其他节点下。其中⼀个节点设置密码即可。依次对每个账户设置密码。全部节点都要重启⼀遍。需要在配置⽂件中开启。个⽤户分别设置密码,⽬录下,证书⽂件名为。功能,并指定证书位置。_es设置账号和密码
文章浏览阅读1.9k次,点赞2次,收藏7次。针对多数据源写入的场景,可以借助MQ实现异步的多源写入,这种情况下各个源的写入逻辑互不干扰,不会由于单个数据源写入异常或缓慢影响其他数据源的写入,虽然整体写入的吞吐量增大了,但是由于MQ消费是异步消费,所以不适合实时业务场景。不易出现数据丢失问题,主要基于MQ消息的消费保障机制,比如ES宕机或者写入失败,还能重新消费MQ消息。针对这种情况,有数据强一致性要求的,就必须双写放到事务中来处理,而一旦用上事物,则性能下降更加明显。可能出现延时问题:MQ是异步消费模型,用户写入的数据不一定可以马上看到,造成延时。_mysql同步es
文章浏览阅读3.6w次,点赞48次,收藏44次。【程序员洲洲送书福利-第十九期】《C++ Core Guidelines解析》
文章浏览阅读1.3k次。当我们在开发Vue应用时,经常需要对表单进行校验,以确保用户输入的数据符合预期。Vue提供了一个强大的校验规则机制,通过定义rules规则,可以方便地对表单进行验证,并给出相应的错误提示。_vue ruler校验
文章浏览阅读2k次,点赞16次,收藏12次。Linux内核源码下载地址及方式_linux源码下载
文章浏览阅读1k次。这样在每天自动生成的索引skywalking_log_xxx就会使用上述模版来生成,timestamp会被设置成date类型。然后此时在–>索引管理–>kibana–>索引模式添加skywalking_log*索引时就会有时间字段了。在通过skywalking将日志收集到es后,由于skywalking收集的日志(skywalking_log索引)没有date类型的字段导致在es上再索引模式中没有时间范围的查询。skywalking收集的日志有时间戳字段timestamp,只是默认为long类型。_skywalking timestamp
文章浏览阅读937次,点赞18次,收藏21次。1.初始化git仓库,使用git int命令。2.添加文件到git仓库,两步走:2.1 使用命令,注意,可反复多次使用,添加多个文件;2.2 使用命令,完成。此笔记是我个人学习记录笔记,通过廖雪峰的笔记进行学习,用自己能理解的笔记记录下来,如果侵权,联系删。不存在任何盈利性质,单纯发布后,用于自己学习回顾。
文章浏览阅读786次,点赞8次,收藏7次。上述示例中的 origin 是远程仓库的名称,https://github.com/example/repository.git 是远程仓库的 URL,(fetch) 表示该远程仓库用于获取更新,(push) 表示该远程仓库用于推送更新。你可以选择在本地仓库创建与远程仓库分支对应的本地分支,也可以直接将本地仓库的分支推送到远程仓库的对应分支。将 替换为远程仓库的名称(例如 origin), 替换为要推送的本地分支的名称, 替换为要推送到的远程分支的名称。_git remote 智能切换仓库
文章浏览阅读1.5k次。配置eslint校验代码工具_eslint 实时校验
文章浏览阅读1.2k次,点赞28次,收藏26次。Git入门基础介绍,什么是Git,如何使用Git,以及Git的工作的基本原理
文章浏览阅读2.7k次。基于官方给出的几种不同环境不同的安装方式,本文将会选择在使用.zip文件在Windows上安装Elasticsearch在Linux或macOS上从存档文件安装ElasticsearchInstall Elasticsearch with Docker (此种方式待定)使用Docker安装Elasticsearch。_elasticsearch安装部署windows
文章浏览阅读3.3k次,点赞5次,收藏11次。【Linux驱动】内核模块编译 —— make modules 的使用(单模块编译、多模块编译)_make modules
文章浏览阅读1k次。docker启动es报错_max virtual memory areas vm.max_map_count [65530] is too low, increase to at
文章浏览阅读4.2k次,点赞2次,收藏6次。使用docker单机安装elasticsearch后再安装kibana时找不到es。_unable to retrieve version information from elasticsearch nodes. security_ex
文章浏览阅读1.1k次。日志处理对于任何现代IT系统都是关键部分,本教程专为新手设计,通过详细解释Logstash的三大核心组件,为您展示如何从零开始搭建强大的日志处理系统。您还将学习如何同步MySQL数据到Elasticsearch,并通过一个"Hello World"示例快速入门。无论您是完全的新手还是有一些基础,本教程都将引导您顺利掌握Logstash的基本操作和高级应用。_logstash mysql
文章浏览阅读1.1w次,点赞5次,收藏25次。执行这条指令之后,你的本地项目就与远程Git仓库建立了连接,你就可以开始对你的代码进行版本追踪和协作开发了。使用“git remote add origin”指令,可以轻松地将本地项目连接到远程Git仓库。git remote set-url origin 执行这条指令之后,Git就会将已经添加的名为“origin”的仓库删除。git remote add origin 其中,是你的远程Git仓库的网址。_git remote add origin