ElasticSearch【有与无】【搜索引擎】【ES7】结构化查询

目录

1.简介

1.1.请求体查询(request body  search)

空查询

1.2.结构化查询 Query DSL

空查询

查询子句

合并多子句

1.3.查询与过滤

1.4.最重要的查询过滤语句

① term

② terms

③ range

④ exists  和  missing

⑤ bool

⑥ match_all

⑦ match

⑧ multi_match

⑨ bool

1.5.查询与过滤条件的合并

单条过滤语句

1.6.验证查询


1.简介

结构化查询

 

1.1.请求体查询(request body  search)

简单查询语句(lite)是一种有效的命令行adhoc查询

大多数查询语句是JSON格式的,即请求体查询(request body  search  )API

不仅仅用来处理查询,还可以高亮返回结果中的片段,并且给出帮助你的用户找寻最好结果的相关数据建议。

 

空查询

【举例】

GET /_search 

GET /index_2014*/type1,type2/_search

GET /_search   // 不允许这种行为,有些HTTP服务允许
{
    "from": 30,
    "size": 10
}

POST /_search
{
    "from": 30,
    "size": 10
}

【结果】

{} 

 

1.2.结构化查询 Query DSL

一种灵活的,多表现形式的查询语言

【举例】

GET /_search
{
    "query": YOUR_QUERY_HERE   // 传递 query  参数,必须
}

空查询

GET /_search
{
    "query": {
        "match_all": {}       // 空查询
    }
}

查询子句

【结构】

{
    QUERY_NAME: {
         ARGUMENT: VALUE,
        ARGUMENT: VALUE,...
    }
}

指向一个指定的字段

{
    QUERY_NAME: {
        FIELD_NAME: {
            ARGUMENT: VALUE,
            ARGUMENT: VALUE,...
        }
    }
}

【举例】

查询在 tweet  字段中包含 elasticsearch

GET /_search
{
    "query": {
        "match": {
            "tweet": "elasticsearch"
        }
    }
}

合并多子句

  • 叶子子句(leaf clauses)  用以在将查询字符串与一个字段(或多字段)进行比较
  • 复合子句(compound)    用以合并其他的子句
compound
{
   "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
}

 

1.3.查询与过滤

结构化语句:结构化查询(Query DSL)和结构化过滤(Filter DSL)

【差异】

query DSL

在查询上下文中,查询会回答这个问题——“这个文档匹不匹配这个查询,它的相关度高么?

如何验证匹配很好理解,如何计算相关度呢?ES中索引的数据都会存储一个_score分值,分值越高就代表越匹配。

查询上下文 是在 使用query进行查询时的执行环境,比如使用search的时候。

查询语句不仅要查找相匹配的文档,还需要计算每个文档的相关性,所以一般来说查询语句要比 过滤语句更耗时,并且查询结果也不可缓存。

倒排索引,一个只匹配少量文档的简单查询语句在百万级文档中的查询效率会与一条经过缓存 的过滤语句旗鼓相当,甚至略占上风。

但是一般情况下,一条经过缓存的过滤查询要远胜一条查询语句的执行效率。

一些query的场景:

  • 与full text search的匹配度最高
  • 包含run单词,如果包含这些单词:runs、running、jog、sprint,也被视为包含run单词
  • 包含quick、brown、fox。这些词越接近,这份文档的相关性就越高

filter DSL

在过滤器上下文中,查询会回答这个问题——“这个文档匹不匹配?

答案很简单,是或者不是,每个文档仅需要1个字节。它不会去计算任何分值,也不会关心返回的排序问题,因此效率会高一点

过滤上下文 是在使用filter参数时候的执行环境,比如在bool查询中使用Must_not或者filter

另外,经常使用过滤器,ES会自动的缓存过滤器的内容,这对于查询来说,会提高很多性能。

过滤语句的目的就是缩小匹配的文档结果集,所以需要仔细检查过滤条件。

一些过滤的情况:

  • 创建日期是否在2013-2014年间?
  • status字段是否为published?
  • lat_lon字段是否在某个坐标的10公里范围内?

【使用场景】

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

 

1.4.最重要的查询过滤语句

 

① term

主要用于精确匹配哪些值

比如数字,日期,布尔值或  not_analyzed  的字符串(未经分析的文本数据类型)

【举例】

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

 

② terms

允许指定多个匹配条件

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

【举例】

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

 

③ range

允许我们按照指定范围查找一批数据

【举例】

{
    "range": {
        "age": {
            "gte": 20,
            "lt": 30
        }
    }
}

范围操作符包含:
gt  :: 大于
gte  :: 大于等于
lt  :: 小于
lte  :: 小于等于

 

④ exists  和  missing

用于查找文档中是否包含指定字段或没有某个字段,类似于SQL语句中的 IS_NULL  条件

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

【举例】

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

 

⑤ 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 }}
        ]
    }
}

 

⑥ match_all

查询到所有文档,是没有查询条件下的默认语句

常用于合并过滤条件

 

⑦ match

标准查询

全文本查询、精确查询都可以使用

【举例】

查询一个全文本字段,它会在真正查询之前用分析器先分析 match  一下查询字符

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

指定了一个确切值,在遇到数字,日期,布尔值或者 not_analyzed  的字符串时,它将搜索给定的值

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

提示: 做精确匹配搜索时,你最好用过滤语句,因为过滤语句可以缓存数据。

查询不可以用类似"+usid:2+tweet:search"这样的语句。
它只能就指定某个确切字段某个确切的值进行搜索,而你要做的就是为它指定正确的字段名以避免语法错误。

⑧ multi_match

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

【举例】

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

 

⑨ 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" }}}
        ]
    }
}

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

 

1.5.查询与过滤条件的合并

【举例】

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

单条过滤语句

【举例】

GET /_search
{
    "query": {
        "filtered": {
            "query": { "match_all": {}},
            "filter": { "term": { "folder": "inbox" }}
        }
    }
}

 

可以过滤掉看起来像垃圾邮件的文档

【举例】

GET /_search
{
    "query": {
        "filtered": {
            "filter": {
                "bool": {
                    "must": { "term": { "folder": "inbox" }},
                    "must_not": {
                        "query": {  // 过滤语句中可以使用 query  查询的方式代替  bool  过滤子句
                            "match": { "email": "urgent business proposal" }
                        }
                    }
                }
            }
        }
    }
}

提示: 
很少用到的过滤语句中包含查询,保留这种用法只是为了语法的完整性。 
只有在过滤中用到全文本匹配的时候才会使用这种结构。

 

1.6.验证查询

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

【举例】

GET /gb/tweet/_validate/query?explain
{
    "query": {
        "tweet" : {
            "match" : "really powerful"
        }
    }
}

explain 可以提供语句错误的更多详情

【结果】

{
    "valid" : false,
    "_shards" : { ... },
    "explanations" : [ {
        "index" : "gb",
        "valid" : false,
        "error" : "org.elasticsearch.index.query.QueryParsingException:[gb] No query registered for [tweet]"
    } ]
}

【举例】

GET /_validate/query?explain
{
    "query": {
        "match" : {
            "tweet" : "really powerful"
        }
    }
}

【结果】

{
    "valid" : true,
    "_shards" : { ... },
    "explanations" : [ {
        "index" : "us",
        "valid" : true,
        "explanation" : "tweet:really tweet:powerful"
    }, {
        "index" : "gb",
        "valid" : true,
        "explanation" : "tweet:really tweet:power"
    } ]
}

 

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

琴 韵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值