Elastic學習之旅 (6) Query DSL

大家好,我是Edison。首先說聲抱歉,這個ES學習系列很久沒更新了,現在繼續吧。

上一篇:ES的倒排索引和Analyzer

什麼是Query DSL

DSL是Domain Specific Language的縮寫,指的是爲特定問題領域設計的計算機語言。這種語言專注於某特定領域的問題解決,因而比通用編程語言更有效率。

在ElasticSearch中,DSL指的是Elasticsearch Query DSL,是一種以JSON形式表示的查詢語言。通過這種語言,用戶可以構建複雜的查詢、排序和過濾數據等操作。這些查詢可以是全文搜索、聚合搜索,也可以是結構化的搜索。

Elastic Query DSL的基本語法如下:

# 基本格式
GET /es_db/_doc/_search {json-request-body}
# 簡化格式
GET /es_db/_search {json-request-body}

match_all

使用match_all就類似於SQL中的SELECT *了,它會匹配所有文檔,但默認只會返回10條數據。這是因爲,_search查詢默認採用的是分頁查詢,每頁size默認值就是10,因此如果想顯示更多,請制定size。

// 匹配所有文檔,默認分頁只返回10條
GET users/_search
{
  "query":
  {
    "match_all":{}
  }
}
// 設置分頁的每頁條數size值爲20
GET users/_search
{
  "query":
  {
    "match_all":{}
  },
  "size": 20
}

分頁查詢 from & size & sort

分頁查詢最重要的3個參數:from 、size 和 sort。

from: 顯示應該跳過的初始結果數量,默認是0。

size: 顯示應該返回的結果數量,默認是10,剛剛有演示。

sort: 根據什麼字段 以及 升序 或 降序 來排序。

// 從第5個文檔開始取10個顯示,並根據用戶名升序排列
GET users/_search
{
  "query":
  {
    "match_all":{}
  },
  "sort": 
  {
    "user": "asc"
  }
  "from": 5
  "size": 20
}

_source 過濾

_source參數就好比SELECT field1, field2,當我們需要只查詢某些特定字段時,就可以使用_source參數來進行過濾。_source支持使用通配符,可以較爲方便的編寫,如:_source["name*","desc*"]。

# 只查詢users中的user和message兩個字段數據,過濾掉其他字段
GET users/_search
{
  "_source": ["user","message"], 
  "query":
  {
    "match_all":{}
  },
  "from": 0,
  "size": 20
}

match 查詢表達式

match 查詢表達式可能是我們用的最多的參數了,它會在匹配時對所查找的關鍵詞進行分詞,然後按照分詞匹配查找。

match 支持以下參數:

  • query 指定匹配的值

  • operator 匹配條件類型

  • and 條件分詞後都要匹配

  • or 條件分詞後有一個匹配即可(默認的operator類型

// 默認爲or => comments字段中有文檔出現任意一個Song or Last or Christmas
GET comments/_search
{
  "query":
  {
    "match":
    {
      "comment": 
      {
        "query": "Song Last Christmas"
      }
    }
  }
}

// 手動指定and => comments字段中有文檔同時出現Song Last Christmas
GET comments/_search
{
  "query":
  {
    "match":
    {
      "comment": 
      {
        "query": "Song Last Christmas",
        "operator": "and"
      }
    }
  }
}

multi_match 多字段查詢表達式

上面演示的是針對單個字段的查詢,那麼如果想要針對多個字段查詢呢?

使用multi_match即可,指定fields:

GET comments/_search
{
  "query":
  {
    "multi_match":
    {
      "query": "Song Last Christmas",
      "fields": ["comments", "address"]
    }
  }
}

match_phrase 短語查詢表達式

短語查詢會對搜索文本進行文本分析,然後纔到索引中尋找搜索的每個分詞並要求分詞相鄰。我們可以通過slop參數設置分詞出現的最大間隔距離,可以通過下面的例子來看看。

// 查詢one love這個短語出現過的文檔
POST movies/_search
{
  "query":
  {
    "match_phrase": {
      "title": {
        "query": "one love"
      }
    }
  }
}
// 只要one和love之間間隔不超過1個詞就都顯示出來
POST movies/_search
{
  "query":
  {
    "match_phrase": {
      "title": {
        "query": "one love",
        "slop": 1
      }
    }
  }
}

搜索結果:One I Love

query_string 與 simple_query_string

Query String類似於URI Query,這種查詢方式的語法和我們在SQL中的WHERE語句就有些類似了,基於OR/AND/NOT等運算符來解析和拆分提供的查詢字符串,我們可以使用 Query String 查詢創建一個較爲複雜的搜索,其中可以包括通配符、跨多個字段的搜索等。

雖然用途廣泛,但是語法較爲嚴格,容易出錯,不推薦在日常查詢中使用。

// 查詢單個字段
GET /bank/_search
{
  "query": {
    "query_string": {
      "default_field": "address",
      "query": "Chengdu AND Shuangliu"
    }
  }
}

// 查詢多個字段
GET /bank/_search
{
  "query": {
    "query_string": {
      "fields": ["name", "address"],
      "query": "(Edison AND Zhou) OR (Chengdu AND Shuangliu)"
    }
  }
}

Simple Query String 顧名思義 就是簡單版Query String,它類似於Query String但會忽略錯誤的語法。此外,它不支持AND OR NOT,會將它們當作字符串來處理。各個Term之間默認的關係是OR,但可以指定Operator來覆蓋。

// 默認operator是OR => 出現其一即可 Edison or Zhou
GET /bank/_search
{
  "query": {
    "simple_query_string": {
      "query": "Edison Zhou",
      "fields": ["name"]
    }
  }
}
// 覆蓋默認operator 改爲AND => 必須完整出現 Edison Zhou
GET /bank/_search
{
  "query": {
    "simple_query_string": {
      "query": "Edison Zhou",
      "fields": ["name"],
      "default_operator": "AND"
    }
  }
}

小結

本篇,我們瞭解了ElasticSearch的Query DSL,並通過一些查詢示例瞭解瞭如何使用它。除了本文中介紹的部分高頻DSL外,你可以通過搜索閱讀其他的關鍵詞進行學習。

參考資料

極客時間,阮一鳴,《ElasticSearch核心技術與實戰

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章