欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

DSL查询与过滤

程序员文章站 2022-07-04 23:02:37
1、 什么是DSL查询 由ES提供丰富且灵活的查询语言叫做DSL查询(Query DSL),它允许你构建更加复杂、强大的查询。 DSL(Domain Specific Language特定领域语言)以JSON请求体的形式出现。 DSL查询是ES提供的通用查询方式,这种方式最大的特点是开发语言的无关性 ......

1、 什么是dsl查询 

  由es提供丰富且灵活的查询语言叫做dsl查询(query dsl),它允许你构建更加复杂强大的查询。

  dsl(domain specific language特定领域语言)以json请求体的形式出现。  

  dsl查询是es提供的通用查询方式,这种方式最大的特点是开发语言无关性,即任意的客户端只要支持http请求,就可以通过json格式的查询数据完成复杂的搜索。

  

  对于简单查询,使用查询字符串比较好,但是对于复杂查询,由于条件多,逻辑嵌套复杂,查询字符串不易组织与表达,且容易出错,因此推荐复杂查询通过dsl使用json内容格式的请求体代替。

 

  dsl有两个部分组成:dsl查询dsl过滤

  dsl过滤语句和dsl查询语句非常相似,但是它们的使用目的却不同:

  dsl过滤(精确查找)查询文档的方式更像是对于我的条件“有”或者“没有”,而dsl查询(模糊查询)则像是“有多像”。

  

  dsl过滤和dsl查询在性能上的区别

      过滤结果可以缓存并应用到后续请求。

      查询语句同时匹配文档,计算相关性,所以更耗时,且不缓存。

     过滤语句可有效地配合查询语句完成文档过滤。

  原则上,使用dsl查询全文本搜索或其他需要进行相关性评分的场景,其它全用dsl过滤。

 

2、 dsl查询 

  使用dsl查询,必须要传递query参数给es。

  get _search

  {"query": your_query_here}

 

  一个常用的相对完整的dsl查询:

get itsource/employee/_search

  {

  "query": {

     "match": {"sex":"女"}

  },

   "_source": ["id","name"],

  "from": 20,

  "size": 10,

  "sort": [{"join_date": "desc"},{"age": "asc"}]

  }

 

  select id,name from t_user where name like “%heh%” order by id desc limit 0,10.

  上面的dsl查询语句代表:查询公司员工性别为女的员工,并按照加入时间降序、年龄升序排列,最终返回第21条至30条数据(只返回名字、年龄和email字段)

3、dsl过滤 

  模糊查询用dsl的查询语句,精确查询用dsl过滤语句。

2.0以上的用法
{   "query": {   "bool": { "must": [         {"match": {"description": "search" }}       ], "filter": { "term": {"age": "12"} }   }   },   "_source": ["id","name"],   "from": 20,   "size": 10,   "sort": [{"join_date": "desc"},{"age": "asc"}] }

 

4、使用dsl查询与过滤

  ① 全匹配(match_all)

  普通搜索(匹配所有文档):

{
  "query" : {
    "match_all" : {}
  }
}

  如果需要使用过滤条件(在所有文档中过滤,红色部分默认可不写):

{
  "query" : {
    "bool" : {
      "must" : [{
        "match_all":{}
      }],
      "filter":{....}
    }
  }
} 

  ② 标准查询(match和multi_match)

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

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

{
  "query": {
    "match": {
      "fullname": "steven king"
    }
  }
} 

  上面的搜索会对steven king分词,并找到包含steven或king的文档,然后给出排序分值。

  如果用 match  下指定了一个确切值,在遇到数字,日期,布尔值或者 not_analyzed的字符串时,它将为你搜索你给定的值,如:

{ "match": { "age": 20 }}

{ "match": { "date": "2016-05-01" }}

{ "match": { "public": true }}

{ "match": { "tag": "full_text" }}

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

{
  "query":{
    "multi_match": {
      "query": "steven king",
      "fields": [ "fullname","title" ]
    }
  }
} 

  上面的搜索同时在fullname和title字段中匹配。

  提示:match一般只用于全文字段的匹配与查询,一般不用于过滤。

  ③单词搜索与过滤(term和terms

{
  "query": {
    "bool": {
      "must": { 
        "match_all": {} 
      }, 
      "filter": { 
        "term": { 
          "age": "20" 
        } 
      } 
    } 
  }
} 

  terms搜索与过滤

{
    "query": {
        "terms": {
            "tags": ["jvm", "hadoop", "lucene"],
            "minimum_match": 2
        }
    }
}
        

  minimum_match:至少匹配个数,默认为1

  ④ 组合条件搜索与过滤(bool

  组合搜索bool可以组合多个查询条件为一个查询对象,查询条件包括must、should和must_not。

  例如:查询爱好有吃米饭,同时也有喜欢游戏或运动,且出生于1990-06-30及之后的人。range:范围

{
  "query": {
    "bool": {
      "must": [{"term": {"hobby": "吃米饭"}}],
      "should": [{"term": {"hobby": "游戏"}}, 
         {"term": {"hobby": "运动"}} 
      ],
      "must_not": [
        {"range" :{"birth_date":{"lt": "1990-06-30"}}} 
      ],
        "filter": [...],
     "minimum_should_match": 1
    }
  }
}

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

  ⑤ 范围查询与过滤(range

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

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

  上例中查询年龄大于等于20并且小于30。

  gt:>    gte:>=   lt:<  lte:<=

  

  ⑥ 存在和缺失过滤器(exists和missing

{
  "query": {
    "bool": {
      "must": [{
        "match_all": {}
      }],
      "filter": {
        "exists": { "field": "gps" }
      }
    }
  }
}

  提示:exists和missing只能用于过滤结果。

 

  ⑦ 前匹配搜索与过滤(prefix

  和term查询相似,前匹配搜索不是精确匹配,而是类似于sql中的like ‘key%’

{
  "query": {
    "prefix": {
      "fullname": "黄"
    }
  }
}

  上例即查询姓黄的所有人。

 

  ⑧ 通配符搜索(wildcard

  使用*代表0~n个,使用?代表1个。

{
  "query": {
    "wildcard": {
      "fullname": "文*华"
    }
  }
}