Elasticsearch-05Elasticsearch之查询与过滤(下)

简介: Elasticsearch-05Elasticsearch之查询与过滤(下)

multi_match 查询

multi_match 查询允许你做 match 查询的基础上同时搜索多个字段

{
    "multi_match": {
        "query": "full text search",
        "fields": [
            "title",
            "body"
        ]
    }
}

POST http://localhost:9200/book/novel/_search

{
  "query":{
    "multi_match":{
      "query":"李四",
      "fields":["author","title"]
    }
  }
}

20190420173832307.png


bool 查询


bool 查询与 bool 过滤相似, 用于合并多个查询子句。 不同的是, bool 过滤可以直接给出是否匹配成功, 而 bool 查询要计算每一个查询子句的 _score (相关性分值)


  • must :: 查询指定文档一定要被包含。
  • must_not :: 查询指定文档一定不要被包含。
  • should :: 查询指定文档, 有则可以为文档相关性加分
{
    "bool": {
        "must": {
            "match": {
                "title": "how to make millions"
            }
        },
        "must_not": {
            "match": {
                "tag": "spam"
            }
        },
        "should": [
            {
                "match": {
                    "tag": "starred"
                }
            },
            {
                "range": {
                    "date": {
                        "gte": "2014-01-01"
                    }
                }
            }
        ]
    }
}


上述查询将会找到 title 字段中包含 “how to make millions”, 并且 “tag” 字段没有被标为 spam. 如果有标识为 "starred"或者发布日期为2014年之前, 那么这些匹配的文档将比同类网站等级高.


如果 bool 查询下没有 must 子句, 那至少应该有一个 should 子句。 但是 如果有 must 子句, 那么没有 should 子句也可以进行查询。


Filter DSL


term 过滤


term 主要用于精确匹配哪些值, 比如数字, 日期, 布尔值或 not_analyzed 的字符串(未经分析的文本数据类型)

term仅允许指定一个匹配条件 ,即 value只能有一个值

举例:过滤查询"public_date" 精确匹配 "2017-08-15"的数据

{
  "query":{
    "term":{
      "public_date": "2017-08-15"
    }
  }
}


POST http://localhost:9200/book/novel/_search


2019042016261695.png


terms 过滤


terms 允许指定多个匹配条件。 如果某个字段指定了多个值, 那么文档需要一起去做匹配。

例子 查询author匹配 "李三"或者"孙悟空"的数据

POST http://localhost:9200/book/novel/_search

{
  "query":{
    "terms":{
      "author":["李三","孙悟空"]
    }
  }
}



20190420163650859.png


range 过滤


range 过滤 按照指定范围查找一批数据

范围操作符包含:

  • gt 大于
  • gte 大于等于
  • lt 小于
  • lte 小于等于

例子: 过滤查询 字数 大于等于1000 小于2000的数据

POST http://localhost:9200/book/novel/_search

{
  "query":{
    "range":{
      "word_count":{
        "gte":1000,
        "lt":"2000"
      }
    }
  }
}



2019042016423097.png

exists 和 missing 过滤


exists 和 missing 过滤可以用于查找文档中是否包含指定字段或没有某个字段, 类似于SQL语句中的 IS_NULL 条件。


这两个过滤只是针对已经查出一批数据来, 但是想区分出某个字段是否存在的时候使用。

目前es不推荐使用missing过滤, 使用bool.must_not + exists来替代

    "bool": {
        "must_not": {
            "exists": {
                "field": "title"
            }
        }
    }

例子 查询是否存在 名为 xxxx 的字段

POST http://localhost:9200/book/novel/_search

{
  "query":{
    "exists":{
      "field":"xxxx"
    }
  }
}



20190420164723683.png


bool 过滤


bool 过滤可以用来合并多个过滤条件查询结果的布尔逻辑,它包含一下操作符:

  • must :: 多个查询条件的完全匹配,相当于 and。
  • must_not :: 多个查询条件的相反匹配,相当于 not。
  • should :: 至少有一个查询条件匹配, 相当于 or。

这些参数可以分别继承一个过滤条件或者一个过滤条件的数组:

例子

{
    "query": {
        "bool": {
            "must": {
                "term": {
                    "folder": "inbox"
                }
            },
            "must_not": {
                "term": {
                    "tag": "spam"
                }
            },
            "should": [
                {
                    "term": {
                        "starred": true
                    }
                },
                {
                    "term": {
                        "unread": true
                    }
                }
            ]
        }
    }
}

查询与过滤条件的合并


查询语句和过滤语句可以放在各自的上下文中。 在 ElasticSearch API 中我们会看到许多带有 query 或 filter 的语句。

这些语句既可以包含单条 query 语句, 也可以包含一条 filter 子句。


换句话说, 这些语句需要首先创建一个 query 或 filter 的上下文关系。


复合查询语句可以加入其他查询子句, 复合过滤语句也可以加入其他过滤子句。 通常情况下, 一条查询语句需要过滤语句的辅助, 全文本搜索除外。


所以说, 查询语句可以包含过滤子句, 反之亦然。 以便于我们切换 query 或 filter 的上下文。 这就要求我们在读懂需求的同时构造正确有效的语句。


带过滤的查询语句


假设我们有这样一条查询语句:

{
    "match": {
        "email": "business opportunity"
    }
}

然后我们想要让这条语句加入 term 过滤, 在收信箱中匹配邮件:

{
    "term": {
        "folder": "inbox"
    }
}


search API中只能包含 query 语句, 所以我们需要用 filtered 来同时包含 “query” 和 “filter” 子句 【过滤查询已被弃用,并在ES 5.0中删除,如下会在我们用的5.x版本中报错】

{
    "filtered": {
        "query": {
            "match": {
                "email": "business opportunity"
            }
        },
        "filter": {
            "term": {
                "folder": "inbox"
            }
        }
    }
}

我们在外层再加入 query 的上下文关系:

{
    "query": {
        "filtered": {
            "query": {
                "match": {
                    "email": "business opportunity"
                }
            },
            "filter": {
                "term": {
                    "folder": "inbox"
                }
            }
        }
    }
}


20190420180505576.png

报错了。。。。改成使用bool / must / filter查询


{
    "query": {
        "bool": {
            "must": {
                "match": {
                    "email": "business opportunity"
                }
            },
            "filter": {
                "term": {
                    "folder": "inbox"
                }
            }
        }
    }
}

单条过滤语句


在 query 上下文中, 如果你只需要一条过滤语句, 比如在匹配全部邮件的时候, 你可以 省略 query 子句( 5.x以后的版本 需要用bool 代替 filtered):

{
    "query": {
        "bool": {
            "filter": {
                "term": {
                    "folder": "inbox"
                }
            }
        }
    }
}

如果一条查询语句没有指定查询范围, 那么它默认使用 match_all 查询 ,等同于

{
    "query": {
        "bool": {
            "must": {
                "match_all": {}
            },
            "filter": {
                "term": {
                    "folder": "inbox"
                }
            }
        }
    }
}


上面说的是 查询中使用过滤。 那过滤中使用查询呢?

我们很少用到的过滤语句中包含查询,为了语法的完整性,ES也支持这种。 只有在过滤中用到全文本匹配时候才会使用这种结构。


验证查询 (_validate)


查询语句可以变得非常复杂, 特别是与不同的分析器和字段映射相结合后。

validate API 可以验证一条查询语句是否合法。

POST http://localhost:9200/book/novel/_validate/query

20190420182142213.png

重点看 valid 的返回结果


20190420182308735.png


查看错误信息


想知道语句非法的具体错误信息, 需要加上 explain 参数:

POST: http://localhost:9200/book/novel/_validate/query?explain

20190420182502431.png


查看ES如何执行的


如果是合法语句的话, 使用 explain 参数可以返回一个带有查询语句的可阅读描述, 可以帮助了解查询语句在ES中是如何执行的

以 以下的JSON为例

{
  "query":{
    "match":{
      "title":"Elasticserach"
    }
  }
}

POST http://localhost:9200/book/novel/_validate/query?explain

关键请求: /_validate/query?explain

返回:

{
    "valid": true,
    "_shards": {
        "total": 1,
        "successful": 1,
        "failed": 0
    },
    "explanations": [
        {
            "index": "book",
            "valid": true,
            "explanation": "+title:elasticserach #_type:novel"
        }
    ]
}


explanation 会为每一个索引返回一段描述, 因为每个索引会有不同的映射关系和分析器. 上面的就只有一个。 ES如何查询是和分词器有关的。

相关实践学习
以电商场景为例搭建AI语义搜索应用
本实验旨在通过阿里云Elasticsearch结合阿里云搜索开发工作台AI模型服务,构建一个高效、精准的语义搜索系统,模拟电商场景,深入理解AI搜索技术原理并掌握其实现过程。
ElasticSearch 最新快速入门教程
本课程由千锋教育提供。全文搜索的需求非常大。而开源的解决办法Elasricsearch(Elastic)就是一个非常好的工具。目前是全文搜索引擎的首选。本系列教程由浅入深讲解了在CentOS7系统下如何搭建ElasticSearch,如何使用Kibana实现各种方式的搜索并详细分析了搜索的原理,最后讲解了在Java应用中如何集成ElasticSearch并实现搜索。  
相关文章
|
9月前
|
数据采集 JSON 数据挖掘
Elasticsearch 的DSL查询,聚合查询与多维度数据统计
Elasticsearch的DSL查询与聚合查询提供了强大的数据检索和统计分析能力。通过合理构建DSL查询,用户可以高效地搜索数据,并使用聚合查询对数据进行多维度统计分析。在实际应用中,灵活运用这些工具不仅能提高查询效率,还能为数据分析提供深入洞察。理解并掌握这些技术,将显著提升在大数据场景中的分析和处理能力。
503 20
|
存储 JSON 监控
大数据-167 ELK Elasticsearch 详细介绍 特点 分片 查询
大数据-167 ELK Elasticsearch 详细介绍 特点 分片 查询
857 4
|
存储 自然语言处理 关系型数据库
Elasticsearch 查询时 term、match、match_phrase、match_phrase_prefix 的区别
【7月更文挑战第3天】Elasticsearch 查询时 term、match、match_phrase、match_phrase_prefix 的区别
|
JSON 自然语言处理 算法
ElasticSearch基础2——DSL查询文档,黑马旅游项目查询功能
DSL查询文档、RestClient查询文档、全文检索查询、精准查询、复合查询、地理坐标查询、分页、排序、高亮、黑马旅游案例
ElasticSearch基础2——DSL查询文档,黑马旅游项目查询功能
|
自然语言处理 搜索推荐 Java
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(一)
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图
327 0
|
存储 自然语言处理 搜索推荐
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(二)
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(二)
305 0
|
自然语言处理 Java 关系型数据库
ElasticSearch 实现分词全文检索 - 聚合查询 cardinality
ElasticSearch 实现分词全文检索 - 聚合查询 cardinality
435 1
|
存储 数据库 索引
面试题ES问题之动态映射的定义如何解决
面试题ES问题之动态映射的定义如何解决
160 1
|
自然语言处理 索引
Elasticsearch 常用查询语句大全
【7月更文挑战第8天】Elasticsearch 常用查询语句大全
|
索引
Elasticsearch 精确查询:术语查询、多术语查询、主键查询、范围查询、存在查询、前缀查询、正则查询与通配符查询
Elasticsearch 精确查询:术语查询、多术语查询、主键查询、范围查询、存在查询、前缀查询、正则查询与通配符查询
262 4

热门文章

最新文章