前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ElasticSearch权威指南学习(结构化查询)

ElasticSearch权威指南学习(结构化查询)

作者头像
老梁
发布2019-09-10 17:21:28
5500
发布2019-09-10 17:21:28
举报

请求体查询

  1. 简单查询语句(lite)是一种有效的命令行adhoc查询。但是,如果你想要善用搜索,你必须使用请求体查询(request body search)API。
  2. 空查询
    • 我们以最简单的 search API开始,空查询将会返回索引中所有的文档。 GET /_search {}
    • 同字符串查询一样,你可以查询一个,多个或_all索引(indices)或类型(types):

    GET /index_2014*/type1,type2/_search {}

    • 你可以使用from及size参数进行分页:

    GET /_search { "from": 30, "size": 10 } 结构化查询 Query DSL

  3. 使用结构化查询,你需要传递query参数: GET /_search { "query": YOUR_QUERY_HERE }
  4. 空查询 - {} - 在功能上等同于使用match_all查询子句,正如其名字一样,匹配所有的文档: GET /_search { "query": { "match_all": {} } } 查询子句
  5. 你可以使用match查询子句用来找寻在tweet字段中找寻包含elasticsearch的成员: GET /_search { "query": { "match": { "tweet": "elasticsearch" } } } 合并多子句
  6. 查询子句就像是搭积木一样,可以合并简单的子句为一个复杂的查询语句
    • 叶子子句(leaf clauses)(比如match子句)用以在将查询字符串与一个字段(或多字段)进行比较
    • 复合子句(compound)用以合并其他的子句。例如,bool子句允许你合并其他的合法子句,must,must_not或者should,如果可能的话:

    { "bool": { "must": { "match": { "tweet": "elasticsearch" }}, "must_not": { "match": { "name": "mary" }}, "should": { "match": { "tweet": "full text" }} } }

    • 复合子句能合并 任意其他查询子句,包括其他的复合子句。 这就意味着复合子句可以相互嵌套,从而实现非常复杂的逻辑。
    • 以下实例查询的是邮件正文中含有“business opportunity”字样的星标邮件或收件箱中正文中含有“business opportunity”字样的非垃圾邮件:

    { "bool": { "must": { "match": { "email": "business opportunity" }}, "should": [ { "match": { "starred": true }}, { "bool": { "must": { "folder": "inbox" }}, "must_not": { "spam": true }} }} ], "minimum_should_match": 1 } } 查询与过滤

  7. 查询与过滤语句非常相似,但是它们由于使用目的不同而稍有差异
  8. 一条过滤语句会询问每个文档的字段值是否包含着特定值
    • created 的日期范围是否在 2013 到 2014 ?
    • status 字段中是否包含单词 "published" ?
    • lat_lon 字段中的地理位置与目标点相距是否不超过10km ?
  9. 一条查询语句会计算每个文档与查询语句的相关性,会给出一个相关性评分 _score,并且 按照相关性对匹配到的文档进行排序。 这种评分方式非常适用于一个没有完全配置结果的全文本搜索

性能差异

  1. 使用过滤语句得到的结果集--一个简单的文档列表,快速匹配运算并存入内存是十分方便的,每个文档仅需要1个字节。这些缓存的过滤结果集与后续请求的结合使用是非常高效的
  2. 查询语句不仅要查找相匹配的文档,还需要计算每个文档的相关性,所以一般来说查询语句要比过滤语句更耗时,并且查询结果也不可缓存。
  3. 幸亏有了倒排索引,一个只匹配少量文档的简单查询语句在百万级文档中的查询效率会与一条经过缓存的过滤语句旗鼓相当,甚至略占上风。但是一般情况下,一条经过缓存的过滤查询要远胜一条查询语句的执行效率。

使用情况

  1. 原则上来说,使用查询语句做全文本搜索或其他需要进行相关性评分的时候,剩下的全部用过滤语句

最重要的查询过滤语句

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

    { "term": { "age": 26 }} { "term": { "date": "2014-09-01" }} { "term": { "public": true }} { "term": { "tag": "full_text" }}

  2. terms 过滤
    • terms 跟 term 有点类似,但 terms 允许指定多个匹配条件。 如果某个字段指定了多个值,那么文档需要一起去做匹配:

    { "terms": { "tag": [ "search", "full_text", "nosql" ] } }

  3. range 过滤
    • range过滤允许我们按照指定范围查找一批数据:

    { "range": { "age": { "gte": 20, "lt": 30 } } } 范围操作符包含: gt :: 大于 gte:: 大于等于 lt :: 小于 lte:: 小于等于

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

    { "exists": { "field": "title" } }

  5. bool 过滤
    • bool 过滤可以用来合并多个过滤条件查询结果的布尔逻辑,它包含一下操作符:
      • must :: 多个查询条件的完全匹配,相当于 and。
      • must_not :: 多个查询条件的相反匹配,相当于 not。
      • should :: 至少有一个查询条件匹配, 相当于 or。
    • 这些参数可以分别继承一个过滤条件或者一个过滤条件的数组

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

  6. match_all 查询
    • 使用match_all 可以查询到所有文档,是没有查询条件下的默认语句。

    { "match_all": {} }

  7. match 查询
    • match查询是一个标准查询,不管你需要全文本查询还是精确查询基本上都要用到它
    • 如果你使用 match 查询一个全文本字段,它会在真正查询之前用分析器先分析match一下查询字符

    { "match": { "tweet": "About Search" } }

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

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

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

    must:: 查询指定文档一定要被包含。 must_not:: 查询指定文档一定不要被包含。 should:: 查询指定文档,有则可以为文档相关性加分。

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

    { "bool": { "must": { "match": { "title": "how to make millions" }}, "must_not": { "match": { "tag": "spam" }}, "should": [ { "match": { "tag": "starred" }}, { "range": { "date": { "gte": "2014-01-01" }}} ] } } 查询与过滤条件的合并

  10. 带过滤的查询语句
    • search API中只能包含 query 语句,所以我们需要用 filtered 来同时包含 "query" 和 "filter" 子句:
    • 在收信箱中匹配邮件

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

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

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

    • ps: 过滤查询已被弃用,并在ES 5.0中删除。现在应该使用bool / must / filter查询

验证查询

  1. 查询语句可以变得非常复杂,特别是与不同的分析器和字段映射相结合后,就会有些难度
  2. validate API 可以验证一条查询语句是否合法 GET /ecommerce/product/_validate/query?explain { "query": { "filtered":{ "query":{ "match":{ "name":"jiajieshi yagao" } }, "filter":{ "term":{ "price":40 } } } } } 结果 { "valid": false, "error": "org.elasticsearch.common.ParsingException: no [query] registered for [filtered]" }
    • ps:可以总结下碰到no [xxx] registered for [xxxx] 这种情况,很大可能是版本升级后,该方法被废除了
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-11-15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 请求体查询
    • 性能差异
      • 使用情况
      • 最重要的查询过滤语句
      • 验证查询
      相关产品与服务
      Elasticsearch Service
      腾讯云 Elasticsearch Service(ES)是云端全托管海量数据检索分析服务,拥有高性能自研内核,集成X-Pack。ES 支持通过自治索引、存算分离、集群巡检等特性轻松管理集群,也支持免运维、自动弹性、按需使用的 Serverless 模式。使用 ES 您可以高效构建信息检索、日志分析、运维监控等服务,它独特的向量检索还可助您构建基于语义、图像的AI深度应用。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档