ElasticSearch 常用的查询过滤语句

973 阅读4分钟

term 过滤

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

#完整的例子, hostname 字段完全匹配成 saaap.wangpos.com 的数据:

{ 
  "query": { 
    "term": { 
      "hostname": "saaap.wangpos.com" 
    } 
  } 
}

terms 过滤

terms 跟 term 有点类似,但 terms 允许指定多个匹配条件:

#完整的例子,所有http的状态是 302 、304 的, 由于ES中状态是数字类型的字段,所有这里我们可以直接这么写。:

{ 
  "query": { 
    "terms": { 
      "status": [ 
        304, 
        302 
      ] 
    } 
  } 
}

range 过滤

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

#一个完整的例子, 请求页面耗时大于1秒的数据,upstream_response_time 是 nginx 日志中的耗时,ES中是数字类型。

{ 
  "query": { 
    "range": { 
      "upstream_response_time": { 
        "gt": 1 
      } 
    } 
  } 
}

exists 和 missing 过滤

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

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

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

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

match 查询

match查询是一个标准查询,不管你需要全文本查询还是精确查询基本上都要用到它:

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

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

multi_match 查询

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

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

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

wildcards 查询

使用标准的shell通配符查询

#查询 hostname 匹配下面shell通配符的:

{ 
  "query": { 
    "wildcard": { 
      "hostname": "wxopen*" 
    } 
  } 
}

regexp 查询

假设您只想匹配以W开头,紧跟着数字的邮政编码。使用regexp查询能够让你写下更复杂的模式: 

#所有以 wxopen 开头的正则

{ 
  "query": { 
    "regexp": { 
      "hostname": "wxopen.*" 
    } 
  } 
}

prefix 查询

以什么字符开头的,可以更简单地用 prefix,如下面的例子:

{ 
  "query": { 
    "prefix": { 
      "hostname": "wxopen" 
    } 
  } 
}

短语匹配(Phrase Matching)

当你需要寻找邻近的几个单词时,你会使用match_phrase查询:

#你需要寻找邻近的几个单词时,你会使用match_phrase查询:

GET /my_index/my_type/_search
{
    "query": {
        "match_phrase": {
            "title": "quick brown fox"
        }
    }
}

bool组合复杂查询 

下例是查询类型为b2t,收入必须大于0的所有单子的click、revenue相关数据

GET rta_daily_report/_search
{
  "query": {
    "bool": {
      "must": [
        {"match": {
          "type": "b2t"
        }}
     ],
     "must_not": [
       {
         "range": {
           "revenue": {
             "lte": 0
           }
         }
       }
     ]
    }
  },
  "sort": [
    {
      "yyyymmdd": {
        "order": "desc"
      }
    }
  ],
  "_source": ["yyyymmdd", "type", "cid", "click", "revenue"],
  "size": 10       
}

查询结果按某个字段进行排序

//javaApi设置查询数量size和对orderstr进行正序
SearchRequestBuilder srb = this.createSearchRequestBuilder(new Date(begin), new Date(end));
srb.setQuery(queryBuilder).setSize(queryParam.getPageIndex() * queryParam.getPageSize()).addSort(orderStr, SortOrder.ASC);

{
  "size" : 5,
  "query" : {
    "bool" : {
      "filter" : [
        {
          "range" : {
            "startTime" : {
              "from" : 1517046960000,
              "to" : 1517048760000
            }
          }
        }
      ]
    }
  },
  "sort" : [{ "startTime" : { "order" : "desc"}}
  ]
}

查询一段时间内的聚合数据

GET rta_daily_report/campaign/_search
{
  "size": 0,
  "aggs": {
    "snaptime": {
      "date_range": {
        "field": "@timestamp",
        "ranges": [
          {
            "from": "now-30d/d",
            "to": "now"
          }
        ]
      },
      "aggs": {
        "sum_revenue": {
          "sum": {
            "field": "revenue"
          }
        }
      }
    }
  }
}

聚合结果进行排序

根据查询到文档数量:聚合结果为查询到文档的数量倒序:"order" : {  "_count" : "desc" }
//在java代码中不能直接使用“_count” 使用如下的方式查询
TermsAggregationBuilder termsAggBuilder=AggregationBuilders.terms(AggAlias.CATEGORY.getValue()).field(cateGoryFieldName);
termsAggBuilder.order(Terms.Order.count(false)).size(5);

{"size": 0, 
  "query" : {
    "bool" : {
      "filter" : [
        { "range" : {
            "startTime" : {
              "from" : 1515655800000,
              "to" : 1516865400000
            }
          } },
        { "term" : {
            "type" : {
              "value" : "URL",
              "boost" : 1.0
            }
          } }
      ]
    }
  },
  "aggregations" : {
    "CATEGORY" : {
      "terms" : {
        "field" : "errorCode",
        "size" : 5,
        "order" : {
          "_count" : "desc"
        }
      }
    }
  }
}

根据子聚合的结果进行排序:

//注意根据上面的语句传入的参数应该是  orderStr===responseTime.avg   ascOrder=true  
AggregationBuilders.terms(AggAlias.CATEGORY.getValue()).field(categoryfieldName).order(Terms.Order.aggregation(orderStr,ascOrder)).size(size)

{
  "query" : {
    "bool" : {
      "filter" : [
        {
          "term" : {
            "type" : {
              "value" : "URL",
              "boost" : 1.0
            }
          }
        }
      ]
    }
  },
  "aggregations" : {
    "CATEGORY" : {
      "terms" : {
        "field" : "name",
        "size" : 5,
        "order" : {"responseTime.avg" : "asc" }
      },
      "aggregations" : {
        "responseTime" : {
          "extended_stats" : {
            "field" : "durationInMillis",
            "sigma" : 2.0
          }
        },
        "error" : {
          "sum" : {
            "script" : {
              "inline" : "def errorTemp=doc['status'].value; if(errorTemp=='0'){return 0;}else{return 1;}",
              "lang" : "painless"
            }
          }
        },
        "apdex" : {
          "avg" : {
            "script" : {
              "inline" : "def responseTemp=doc['durationInMillis'].value; if(responseTemp>params.threshold){return 0.5;}else{return 1;}",
              "lang" : "painless",
              "params" : {
                "threshold" : 20.0
              }
            }
          }
        },
        "errorRate" : {
          "percentile_ranks" : {
            "script" : {
              "inline" : "def errorTemp=doc['status'].value; if(errorTemp=='0'){return 1;}else{return 0;}",
              "lang" : "painless"
            },
            "values" : [
              0.0
            ],
            "keyed" : true,
            "tdigest" : {
              "compression" : 100.0
            }
          }
        }
      }
    }
  }
}