这篇博客主要分为 :Query查询Filter查询。有关复合查询聚合查询也会单独写篇博客。

一、概念

1、概念

一个查询语句究竟具有什么样的行为和得到什么结果,主要取决于它到底是处Query还是Filter。两者有很大区别,我们来看下:

Query context 查询上下文 这种语句在执行时既要计算文档是否匹配,还要计算文档相对于其他文档的匹配度有多高,匹配度越高,_score 分数就越高

Filter context 过滤上下文 过滤上下文中的语句在执行时只关心文档是否和查询匹配,不会计算匹配度,也就是得分

看下官方的例子

GET /_search
{
"query": {
"bool": {
"must": [
{ "match": { "title": "Search" }},
{ "match": { "content": "Elasticsearch" }}
],
"filter": [
{ "term": { "status": "published" }},
{ "range": { "publish_date": { "gte": "2015-01-01" }}}
]
}
}
}

对上面的例子分析下:

  1. query 参数表示整个语句是处于 query context 中
  2. bool 和 match 语句被用在 query context 中,也就是说它们会计算每个文档的匹配度(_score)
  3. filter 参数则表示这个子查询处于 filter context 中
  4. filter 语句中的 term 和 range 语句用在 filter context 中,它们只起到过滤的作用,并不会计算文档的得分。

2、查询数据准备

1)创建索引

PUT student
{
"settings":{
"number_of_shards":1,
"number_of_replicas":1
},
"mappings":{
"properties":{
"name":{"type":"text"},
"address":{"type":"keyword"},
"age":{"type":"integer"},
"interests":{"type":"text"},
"birthday":{"type":"date"}
}
}
}

2)添加测试数据

POST /student/_doc/1
{
"name":"徐小小",
"address":"杭州",
"age":3,
"interests":"唱歌 画画 跳舞",
"birthday":"2017-06-19"
} POST /student/_doc/2
{
"name":"刘德华",
"address":"香港",
"age":28,
"interests":"演戏 旅游",
"birthday":"1980-06-19"
} POST /student/_doc/3
{
"name":"张小斐",
"address":"北京",
"age":28,
"interests":"小品 旅游",
"birthday":"1990-06-19"
} POST /student/_doc/4
{
"name":"王小宝",
"address":"德州",
"age":63,
"interests":"演戏 小品 打牌",
"birthday":"1956-06-19"
} POST /student/_doc/5
{
"name":"向华强",
"address":"香港",
"age":31,
"interests":"演戏 主持",
"birthday":"1958-06-19"
}

看是否成功

GET _cat/count/student?v

可以看出索引已经存在,并且下面有5条数据。

二、Query查询

1、match查询

match query: 知道分词器的存在,会对filed进行分词操作,然后再查询
match_all: 查询所有文档
multi_match: 可以指定多个字段
match_phrase: 短语匹配查询,ElasticSearch引擎首先分析(analyze)查询字符串,从分析后的文本中构建短语查询,这意味着必须匹配短语中的所有分词,

并且保证各个分词的相对位置不变

#1、 查询年龄为3的(命中:ID = 1)
GET student/_search
{
"query":{
"match":{"age": 3}
}
} #2、查询兴趣里包含'演戏'的 (命中 ID = 2,5,4)
GET student/_search
{
"query":{
"match":{"interests": "演戏"}
}
}
#这里只要interests包含'演戏','演','戏'的都会命中 #3、查询索引所有文档 (命中 ID = 1,2,3,4,5)
GET student/_search
{
"query":{
"match_all": {}
}
} #4、查询name和address包含'德' (命中 ID = 2)
GET student/_search
{
"query":{
"multi_match": {
"query": "德",
"fields":["name","address"]
}
}
}
#说明 这里文档ID为4的address为'德州',应该也包含'德',但却没有被命中,原因是我们索引结构中,address属性是一个keyword类型,它是需要完全匹配,而不是包含的关系。
#如果这里query为'德州'就可以命中2条数据。 #5、查询兴趣里包含'演员'的 (命中 无)
GET student/_search
{
"query":{
"match_phrase":{"interests": "演员"}
}
}
# 这里和match的区别是这里是真正包含'演员',而不是只要满足其中一个字就会被模糊命中

重点 通过上面的例子有两点比较重要

1)、文档字段属性如果是一个keyword类型,那就需要完全匹配才能命中。好比这个字段值是12345,那么你不论是1234还是123456都不会命中。

2)、如果是match_phrase,那就是真正的包含关系。好比这个字段值是12345,那么你是1234就会命中,而123456不会命中。因为12345包含1234而不包含123456。

2、term查询和terms查询

term query: 会去倒排索引中寻找确切的term,它并不知道分词器的存在。这种查询适合keyword 、numeric、date

term:查询某个字段为该关键词的文档(它是相等关系而不是包含关系)

terms:查询某个字段里含有多个关键词的文档

#1、查询地址等于'香港'的文档 (命中:ID = 2,5)
GET student/_search
{
"query":{
"term":{ "address":"香港"}
}
}
#如果仅检索'香'那是无法命中的,因为keyword需要完全匹配才能命中 #2、查询地址等于"香港"或"北京"的 (命中: ID =2,3,5)
GET student/_search
{
"query":{
"terms":{
"address":["香港","北京"]
}
}
}

3、控制查询返回的数量

#返回前两条数据 (命中: ID = 2,5)
GET student/_search
{
"from":0,
"size":2,
"query":{
"match":{"interests": "演戏"}
}
}

4、指定返回的字段

GET student/_search
{
"_source":["name","age"],
"query":{
"match":{"interests": "演戏"}
}
}

5、显示要的字段、去除不需要的字段、可以使用通配符*

GET student/_search
{
"query":{
"match_all": {}
},
"_source":{
"includes": "addr*",
"excludes": ["name","bir*"]
}
}

6、排序

GET student/_search
{
"query":{
"match_all": {}
},
"sort":[{
"age":{"order": "desc"}
}]
}

7、 范围查询

range: 实现范围查询

include_lower: 是否包含范围的左边界,默认是true

include_upper: 是否包含范围的右边界,默认是true

#1、查询生日的范围 (命中 ID = 2,4,5)
GET student/_search
{
"query": {
"range": {
"birthday": {
"from": "1950-01-11",
"to": "1990-01-11",
"include_lower": true,
"include_upper": false
}
}
}
} #2、查询年纪18到28 (命中 ID = 2,3)
GET student/_search
{
"query": {
"range": {
"age": {
"from": 18,
"to": 28,
"include_lower": true,
"include_upper": true
}
}
}
}

8、wildcard查询

允许使用通配符* 和 ?来进行查询
* 代表0个或多个字符
? 代表任意一个字符

#1、查询姓名'徐'开头的 (命中 ID = 1)
GET student/_search
{
"query": {
"wildcard": {
"name": "徐*"
}
}
} #查不到数据
GET student/_search
{
"query": {
"wildcard": {
"name": "徐小?"
}
}
}
#疑惑:按照正常我觉得这里是可以查到数据的,因为有个name为'徐小小'可以匹配,估计是因为是中文的原因,所以没有匹配到

9、fuzzy实现模糊查询

模糊查询可以在Match和 Multi-Match查询中使用以便解决拼写的错误,模糊度是基于Levenshteindistance计算与原单词的距离。使用如下:

(命中: ID = 2,5,4)
GET student/_search
{
"query": {
"fuzzy": {
"interests": {
"value": "演"
}
}
}
}
#疑惑 :如果我把'演'改成'演员'就查不到数据了

有关fuzzy描述可以参考一篇文章:Elasticsearch的误拼写时的fuzzy模糊搜索技术

10、高亮搜索结果

{
"query":{
"match":{
"interests": "演戏"
}
},
"highlight": {
"fields": {
"interests": {}
}
}
}

三、Filter查询

filter是不计算相关性的,同时可以cache。因此,filter速度要快于query

#1、获取年龄为3的 (命中 ID = 1)
GET student/_search
{
"post_filter":{
"term":{"age": 3}
}
} #2、查询年纪为3或者63的 (命中 ID = 1,4)
GET student/_search
{
"post_filter":{
"terms":{"age":[3,63]}
}
}
MAKEFILE 复制 全屏

Elasticsearch(6) --- Query查询和Filter查询的更多相关文章

  1. Elasticsearch(5) --- Query查询和Filter查询

    Elasticsearch(5) --- Query查询和Filter查询 这篇博客主要分为 :Query查询和Filter查询.有关复合查询.聚合查询也会单独写篇博客. 一.概念 1.概念 一个查询 ...

  2. ElasticSearch的 Query DSL 和 Filter DSL

    Elasticsearch支持很多查询方式,其中一种就是DSL,它是把请求写在JSON里面,然后进行相关的查询. Query DSL 与 Filter DSL DSL查询语言中存在两种:查询DSL(q ...

  3. 【转】elasticsearch的查询器query与过滤器filter的区别

    很多刚学elasticsearch的人对于查询方面很是苦恼,说实话es的查询语法真心不简单-  当然你如果入门之后,会发现elasticsearch的rest api设计是多么有意思. 说正题,ela ...

  4. Elasticsearch Span Query跨度查询

    ES基于Lucene开发,因此也继承了Lucene的一些多样化的查询,比如本篇说的Span Query跨度查询,就是基于Lucene中的SpanTermQuery以及其他的Query封装出的DSL,接 ...

  5. python查询elasticsearch(Query DSL) 实例

    import datetime import sys import getopt import hashlib from elasticsearch import Elasticsearch &quo ...

  6. elasticsearch Terms Query 实现类似于sql in查询

    本文demo基于elasticsearch 5.1.1,  项目中使用的还是较早的版本 例如 import com.alibaba.fastjson.JSON; import org.elastics ...

  7. ElasticSearch 5学习(10)——结构化查询(包括新特性)

    之前我们所有的查询都属于命令行查询,但是不利于复杂的查询,而且一般在项目开发中不使用命令行查询方式,只有在调试测试时使用简单命令行查询,但是,如果想要善用搜索,我们必须使用请求体查询(request ...

  8. Elasticsearch .Net Client NEST 多条件查询示例

    Elasticsearch .Net Client NEST 多条件查询示例 /// <summary> /// 多条件搜索例子 /// </summary> public c ...

  9. Elasticsearch 之 query与filter区别

    转载: http://xiaorui.cc/category/elasticsearch/ http://blog.csdn.net/asia_kobe/article/details/5056301 ...

  10. Elasticsearch教程(九) elasticsearch 查询数据 | 分页查询

    Elasticsearch  的查询很灵活,并且有Filter,有分组功能,还有ScriptFilter等等,所以很强大.下面上代码: 一个简单的查询,返回一个List<对象> ..    ...

随机推荐

  1. Maven的顶级功能——依赖管理

    依赖管理 依赖管理解决的问题 我们学完一个语言的语法之后,我们应该都能知道函数的引用或者类的创建等了.为了方便管理,我们就会把一些特定的功能实现写在一个代码文件中,我们只需要使用的时候导入就行了,这样 ...

  2. 机器学习框架推理流程简述(以一项部署在windows上的MNN框架大模型部署过程为例子)

    一.写在前面 公司正好有这个需求,故我这边简单接受进行模型的部署和demo程序的编写,顺便学习了解整个大模型的部署全流程.这篇博客会简单提到大模型部署的全流程,侧重点在推理这里.并且这篇博客也是结合之 ...

  3. HTTP相关返回值异常如何解决(上篇)

    ​ 今天我们讲讲HTTP相关返回值异常如何解决(实例持续更新中) 一.HTTP介绍 HTTP(超文本传输协议,Hypertext Transfer Protocol)是用于在网络上进行数据交换的应用层 ...

  4. Apache Log4j2远程命令执行漏洞复现

    目录 漏洞原理 复现 漏洞修复 Apache Log4j2 是一个基于Java的日志记录工具,被广泛应用于业务系统开发,开发者可以利用该工具将程序的输入输出信息进行日志记录.Log4j2 远程代码执行 ...

  5. Impala学习--Impala概述,Impala系统架构

    Imapla概述 Impala是Cloudera公司的一个实时海量查询产品.是对于已有Hive产品的补充.Impala采用了和Hive相同的类SQL接口,但并没有采用MapRed框架执行任务,而是采用 ...

  6. 使用Aurora在PPT中插入Latex公式

    应用场景: (1) 在PPT中插入Latex公式 (2) 当点击PPT中的公式,出现提示 "无法找到 服务器应用程序.源文件.和项目,或返回的未知错误.请重新安装服务程序." 的时 ...

  7. ZCMU-1053

    比较简单记录一下主要感觉它这个题目没说清楚,题目要求:先有n,接着给出长度为n的标准组,然后给出猜测组,输出的两个数一个是有多少个是相对应的既相同坐标其数值也相同,后一个是两个都有但是位置不同(不含已 ...

  8. 实用&free的音频格式转化工具

    最近写的博客居然是7年前,今天给小朋友下载歌曲时在网上搜了好多格式转化的方法,挨个尝试了之后发现好多是收费的,或者不支持某种格式转化的,但还是大浪淘沙到一些实用的工具.分享给大家参考,同时也督促自己不 ...

  9. CentOS7.8安装k8s

    1, 安装 docker / kubelet # 在 master 节点和 worker 节点都要执行 \# 最后一个参数 1.20.6 用于指定 kubenetes 版本,支持所有 1.20.x 版 ...

  10. C/C++实例汇集(1)

    1.用代码判断一个系统是16位系统还是32位系统? 以下是几种常见编程语言中判断系统是 16 位还是 32 位的代码示例 C语言: #include <stdio.h> int main( ...