专业的编程技术博客社区

网站首页 > 博客文章 正文

Elasticdearch系列(二):Query DSL查询入门

baijin 2024-10-24 08:46:11 博客文章 11 ℃ 0 评论

Query DSL:查询表达式,是一种非常灵活又富有表现力的查询语言,采用JSON接口的方式实现丰富的查询,并使你的查询语句更灵活、准确易读。

查询&过滤

Elasticsearch中的数据检索分为两种情况:查询 & 过滤

  • Query查询会对检索结果进行评分,注重点是匹配程度!比如检索"运维咖啡吧"与文档的标题有多匹配,计算的是查询与文档的相关程度,计算完成后会算出一个评分,记录在_score中,并最终按照_score字段来对所有检索到的文档进行排序;
  • Filter过滤不会对检索结果进行评分,注重点是是否匹配!比如检索"运维咖啡吧"是否匹配文档的标题,结果只有匹配或者不匹配,因为只是对结果进行简单的匹配,所以计算起来也非常快,并且过滤的结果会被缓存到内存中,性能比Query查询高很多;

简单查询

一个最简单的DSL查询如下:

GET /_search
{
  "query": {
  "match_all": {}
  }
}
  • /_search:查找整个ES中所有索引的内容;
  • query:查询关键字,类似的还有aggs为聚合关键字等;
  • match_all:匹配所有的文档,也可以写成match_none不匹配任何文档;
{
  "took": 12590,
  "timed_out": false,	
  "num_reduce_phases": 6,
  "_shards": {
  "total": 13,
  "successful": 13,
  "skipped": 0,
  "failed": 0
  },
  "hits": {
      "total": 63246,
      "max_score": 1,
      "hits": [	
       {	
          "_index": ".kibana",
          "_type": "doc",
          "_id": "url:ec540365d822e8955cf2fa085db189c2",
          "_score": 1,
          "_source": {
            "type": "url",
            "updated_at": "2020-07-29T14:59:46.075Z",
            "url": {
               "url": "/app/kibana",
               "accessCount": 0,
               "createDate": "2020-07-09T07:19:46.075Z",
               "accessDate": "2020-07-09T07:19:46.075Z"
             }
          }
       },
        ......
       }
        }
  • took:表示我们执行整个搜索请求消耗了多少毫秒;
  • time_out:表示本次查询是否超时;
  • _shards:分片信息,显示查询中参与的分片信息,成功多少分片失败多少分片;
  • hits:匹配到的文档的信息,其中total标识匹配到的文档总数,max_score为文档中所有_score的最大值;
  • hits数组:查询到的文档结果,默认包含查询结果的前十个文档,每个文档都包含_index,_type,_id,_score和_score数据;结果文档默认是按照相关度(_score)进行降序排列,也就是说最先返回的是相关度最高的文档;

指定索引查询

上面的查询会搜索ES中的所有索引,但是我们通常情况下,只需要去固定一个或者几个索引中搜索:

  • 指定一个固定的索引:wangfei_material_index为索引名称
GET /wangfei_material_index/_search
  • 指定多个固定索引,多个固定索引名逗号分隔:wangfei_material_index1(_index2)为索引名称
GET /wangfei_material_index1,wangfei_material_index2/_search
  • 用*号匹配,在匹配到的所有索引下查找数据
GET /wangfei_material_index*/_search

分页查询

上边有说到查询结果hits默认只展示10个文档,那我们如何查询10个以后的文档呢?ES中给了size和from两个参数:

  • size:设置一次返回的结果数量,也就是hits中文档数量,默认值为10;
  • from:设置从第几个结果开始往后查询,默认值为0;
GET /wangfei_material_index/_search
{
  "size": 5,
  "from": 10,
  "query":{
	"match_all": {}
  }
}

全文查询

上边有用到一个match_all的全文查询关键字,match_all为查询所有记录,常用的查询关键字在ES中还有以下几个:

  • match -- 最简单的查询,例如查找host为feiw.com的所有记录;
GET /wangfei_material_index/_search
{
  "query": {
  "match": {
    "host": "feiw.com"
    }
  }
}
  • multi_match -- 在多个字段上执行相同的match查询,例如查询host或manager字段中包含feiw.com的记录;
GET /wangfei_material_index/_search
{
  "query": {
    "multi_match": {
      "query": "feiw.com",
      "fields": ["host", "manager"]
    }
  }
}
  • query_string -- 在查询中使用AND或者OR来完成复杂的查询,例如查询host为a.feiw.com或者b.feiw.com的所有记录(simple_query_string 是通过+或|替代query_string中的AND或OR);
GET /wangfei_material_index/_search
{
  "query": {
    "query_string": {
      "query": "(a.feiw.com) OR (b.feiw.com)",
      "fields": ["host"]
    }
  }
}
  • term -- 用来精准匹配,精准匹配的值可以是数字、时间、布尔值或者设置了not_analyzed不分词的字符串;
GET /wangfei_material_index/_search
{
  "query": {
    "term": {
      "status": 200
    }
  }
}
	
GET /wangfei_material_index/_search
{
  "query": {
    "terms": {
      "status": [200,500]
    }
  }
}
  • range -- 用来查询落在指定区间范围内的数字或者时间;
GET /wangfei_material_index/_search
{
  "query": {
    "range": {
      "status": {
        "gte": 400,
        "lte": 599
      }
    }
  }
}

当使用日期作为范围查询时,需要注意日期的格式,官方支持的日期格式主要有两种:

  1. 时间戳,注意是毫秒粒度;
  2. 日期字符串,日期格式可以自定义,通过format字段指定匹配的格式,如果格式多个可以使用||分隔;
GET /wangfei_material_index/_search
{
  "query": {
    "range": {
      "@timestamp": {
        "gte": "2019-05-13 18:30:00",
        "lte": "2019-05-14",
        "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd",
        "time_zone": "+08:00"
      }
    }
  }
}

【注意】:Elasticsarch中默认使用的是UTC时间,所以我们在使用时要通过time_zone设置时区。

组合查询

通常我们需要将很多的条件组合在一起查询最后的结果,这时需要使用ES提供的bool实现。例如我们需要查询host为a.feiw.com且manager为11085364且status不为200的所有数据:

GET /wangfei_material_index/_search
{
  "query": {
    "bool": {
      "filter": [
        {
        "match": {
        "host": "a.feiw.com"
        }
      },
      {
        "match": {
          "manager": "11085364"
        }
      }
      ],
      "must_not": {
        "match": {
          "status": 200
        }
      }
    }
  }
}

这里主要有四个关键字来组合查询之间的关系,分别是:

  1. must:类似SQL中的AND,必须包含;
  2. must_not:类似SLQ中的NOT,必须不包含;
  3. should:满足这些条件中的任何条件都会增加评分_score,不满足也不影响,should只影响查询结果的_score值,并不会影响结果的内容;
  4. filter:与must类似,但不会对结果进行相关性评分_score,大多数情况下我们对日志的需要都无相关性的要求。所以建议查询的过程中多使用filter。

后文

Elasticsearch的查询博大精深,本篇文章属于基础入门,内容部分来源于官网以及学习笔记,希望帮到刚入门的小伙伴???!


往期精彩文章

Elasticsearch系列:

Elasticsearch系列(一):Elasticsearch入门引言

Redis系列:

Redis系列(十):Redis面试系列问题(集群篇)

MySQL系列:

MySQL系列(五):精华篇

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表