DSL查詢與過濾


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": "文*華"
    }
  }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM