elasticsearh请求体查询

来源:互联网 发布:mysql select count 编辑:程序博客网 时间:2024/06/01 09:27

请求体查询

  • 之所以成为请求体查询(Full-Body Search)。是因为大部分参数都是通过http请求而非查询字符串来传递(简易查询—query-string search)
  • elasticsearch查询习惯用GET请求带上body

空查询

  • 空请求体
GET /_search{}
  • 翻页:
GET /_search{  "from": 30,  "size": 10}
  • 在1到多个索引或type中查询
GET /index_2014*/type1,type2/_search{}

查询表达式(Query DSL)

  • match_all查询,功能上等价于空查询
GET /_search{    "query": {        "match_all": {}    }}
  • 匹配单个字段
GET /_search{    "query": {        "match": {            "tweet": "elasticsearch"        }    }}
  • 叶子语句:如match用于将查询字符串和一个(或多个)字段对比
  • 复合语句,主要用于合并其它查询语句,如bool,例子如下
{    "bool": {        "must":     { "match": { "tweet": "elasticsearch" }},# 与        "must_not": { "match": { "name":  "mary" }},        # 非        "should":   { "match": { "tweet": "full text" }},   #shoule-或        "filter":   { "range": { "age" : { "gt" : 30 }} }  # filter语句不评分    }}

查询与过滤

  • 当使用查询时,查询就变成了一个“评分”的查询,_score`打分,按分数排序,全文搜索几乎没有完全 “正确” 的答案,只有更接近的答案
  • 当使用过滤时,查询被设置成一个“不评分”或者“过滤”查询,yes 或者 no
  • 过滤查询性能:快,non-scoring queries(不评分),结果会被缓存到内存以便快速读取
  • 评分查询:需要找出匹配文档、计算相关性、结果不缓存,速度稍慢
  • 过滤(filtering)的目标是减少那些需要通过评分查询进行检查的文档,查询语句来进行全文搜索或者其它任何需要影响相关性得分的搜索,其他都使用过滤

最重要的查询

  • match_all,查询所有,经常与 filter 结合使用,在没有指定查询方式时,它是默认的查询
{ "match_all": {}}
  • match查询:可以全文搜索和精确查询
    1. 全文查询

      { "match": { "tweet": "About Search" }}
    2. 精确匹配(数字、日期、布尔、not_analyzed字段),精确查询可能需要filter语句来取代query,因为filter会被缓存

      { "match": { "age": 26 }}
      { "match": { "date": "2014-09-01" }}
      { "match": { "public": true }}
      { "match": { "tag": "full_text" }}
  • muti_match查询:可以在多个字段执行相同的match
PUT /megacorp/employee/1{"first_name" : "John","last_name" : "Smith","score" : 25,"about" : "I love to go rock climbing","interests": [ "sports", "music" ]}PUT /megacorp/employee/2{"first_name" : "John","last_name" : "Smith","age" : 25,"about" : "I love to go rock climbing","interests": [ "sports", "music" ]}GET /_search{  "query": {    "multi_match": {      "query": "25",      "fields": ["age","score"]    }  }}结果是2
  • range查询,数字、时间范围查找
{    "range": {        "age": {            "gte":  20,            "lt":   30        }    }}
  • term查询,精确值
{ "term": { "age":    26           }}{ "term": { "date":   "2014-09-01" }}{ "term": { "public": true         }}{ "term": { "tag":    "full_text"  }}   # not_analyzed字串
  • terms查询,同term,进行多值匹配,只有指定值有任何一个值满足,则这个文档满足条件,且不分析
{ "terms": { "tag": [ "search", "full_text", "nosql" ] }}
  • exists查询和missing查询: 用于查找指定字段中有值或无值,常用于查询某个字段有值或无值情况
GET /_search{  "query": {    "exists": {      "field": "first_name"    }  }}

query_exists

组合多查询

  • bool实现组合查询语句

  • must 文档必须匹配这些条件

  • must_not 文档不匹配这些条件的才能被包含进来
  • should 满足这些语句中的任意语句,将增加 _score,,否则,无任何影响。它们主要用于修正每个文档的相关性得分
  • filter必须匹配(以不评分、过滤模式来进行),对评分没有贡献

  • 评分:每个子查询都独自计算文档相关性得分,计算出来后,bool查询将这些得分合并切返回一个代表bool操作的得分,例子:

该例用于查找 title 字段匹配 how to make millions 并且不被标识为 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" }}}        ]    }}
  • 增加带过滤器查询,如不想因为以上查询因时间影响得分,可增加filter查询
{    "bool": {        "must":     { "match": { "title": "how to make millions" }},        "must_not": { "match": { "tag":   "spam" }},        "should": [            { "match": { "tag": "starred" }}        ],        "filter": {          "range": { "date": { "gte": "2014-01-01" }}        }    }}
  • 如果需要通过不同标准过滤文档,bool查询本身也可以被用做不评分的查询
{    "bool": {        "must":     { "match": { "title": "how to make millions" }},        "must_not": { "match": { "tag":   "spam" }},        "should": [            { "match": { "tag": "starred" }}        ],        "filter": {          "bool": {              "must": [                  { "range": { "date": { "gte": "2014-01-01" }}},                  { "range": { "price": { "lte": 29.99 }}}              ],              "must_not": [                  { "term": { "category": "ebooks" }}              ]          }        }    }}
  • constant_score,将一个不变的常量评分(默认)应用于所有匹配的文档,经常用于你需要执行一个 filter 而没有其它查询(例如,评分查询)的情况下,可以使用它来取代只有 filter 语句的 bool 查询。在性能上是完全相同的,以下两查询结果评分不同,其他都同
GET /_search{  "query": {    "bool": {      "filter": {        "match": {          "first_name": "John"        }      }    }  }}# 评分为0GET /_search{  "query": {    "constant_score": {      "filter": {        "match": {          "first_name": "John"        }      }    }  }}# 评分为1

验证查询

  • 当查询复杂时,需要验证查询是否正确,可以使用 validate-query API
GET /gb/tweet/_validate/query{   "query": {      "tweet" : {         "match" : "really powerful"      }   }}

结果:

{  "valid" :         false,  "_shards" : {    "total" :       1,    "successful" :  1,    "failed" :      0  }}
  • 理解错误信息,可以加上explain参数
GET /gb/tweet/_validate/query?explain{   "query": {      "tweet" : {         "match" : "really powerful"      }   }}

结果:

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

得出tweet字段不存在

  • 对于合法查询,explain参数会返回可定描述,我们查询的没个index都会反回对应explanation
GET /_validate/query?explain{   "query": {      "match" : {         "first_name" : "John"      }   }}

结果:
explain_success