es 筆記二之基礎查詢

Hunter發表於2023-04-12
本文首發於公眾號:Hunter後端
原文連結:es筆記二之基礎查詢

這一篇筆記介紹 es 的基礎查詢。

基礎查詢包括很多,比如排序,類似資料庫 limit 的操作,like 操作,與或非等,對於這些操作,我會在介紹他們的用法之後加上對應的資料庫 sql 便於理解。

注意: 下面的操作都在 kibana 中實現

以下是本篇文章目錄:

  1. 全量查詢
  2. 返回資料排序
  3. 限制返回條數
  4. 指定欄位搜尋
  5. 多條件查詢
  6. 大小於過濾

1、全量查詢

如果是想要檢視 es 中都有哪些 index,可以如下操作:

GET /_cat/indices

然後可以看到在右側會輸出所有的 index,其中就包含我們上一篇筆記匯入的 bank 資料,接下來我們使用 bank 作為查詢示例。

如果我們想檢視 bank 中的全部資料,可以如下操作,但是不指定 size 引數的話預設最多隻返回 10 條資料:

GET /bank/_search

出來的結果大致如下:

{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1000,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "bank",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "account_number" : 1,
          "balance" : 39225,
          "firstname" : "Amber",
          "lastname" : "Duke",
          "age" : 32,
          "gender" : "M",
          "address" : "880 Holmes Lane",
          "employer" : "Pyrami",
          "email" : "amberduke@pyrami.com",
          "city" : "Brogan",
          "state" : "IL"
        }
      },
      ...
    ]
  }
}

took 表示查詢花費了多少時間,以毫秒為單位

time_out 表示查詢是否超時

_shards 表示分片的查詢資訊,表示有多少個分片被查詢,失敗,和跳過

然後查詢的結果都被放在 hits 欄位下,在 hits 資訊中,

hits.total 表示查詢到了多少匹配的資料

hits.hits 是一個陣列,包含了返回資訊的全部內容,每個元素都是單個查詢的返回結果。

在每個元素中,_index,_type,_id,_score 表示單條資料的所屬的資料庫資訊

_source 其中包含了獲取資訊的欄位資訊,如果沒有指定欄位,則返回該資料所有欄位。

2、返回資料排序

查詢出的資料如果想要以某種順序返回,可以使用 sort 來排序

比如說根據 balance 倒序排序

GET /bank/_search
{
  "sort": [
    {"balance": {"order": "desc"}}
  ]
}

這條資料對應於 sql 中的語法就是:

order by balance desc

sort 後接一個陣列,表示可以根據多個欄位進行正序,逆序的排序方式。

3、限制返回條數

在前面的搜尋中可以看出,如果不限定返回條數,系統會預設返回 10 條資料,在 es 中有類似於 MySQL 的 limit 和 offset 的操作,那就是 size 和 from。

from 表示從第 n 個開始獲取資料,從 0 開始取值

size 表示獲取資料量的大小。

比如說從第0條資料開始,獲取5條資料,可以如下操作:

GET /bank/_search
{
  "sort": [
    {"balance": {"order": "asc"}}
  ],
  "from": 0,
  "size": 5
}

對應於 sql 語法是:

limit 5 offset 0;

4、指定欄位搜尋

關於欄位搜尋,有幾個關鍵字,match,match_phrase等。

match 表示模糊搜尋,會將搜尋的內容先進行分詞操作,然後搜尋,比如我們搜尋 bank 這個 index 中 address 欄位中包含 "cove" 或者 包含 "lane" 的的資料,我們可以如下操作:

GET /bank/_search
{
  "query": {
    "match": {"address": "Cove Lane"}
  }
}

這條語句類似於 sql 中的:

where address like "%cove%" or address like "%lane%"

只要 address 的字元包含 cove 或者 lane 之一即可。

而如果我們想要實現 cove lane 作為一個整體進行查詢,我們可以使用 match_phrase 來實現:

GET /bank/_search
{
  "query": {
    "match_phrase": {"address": "Cove Lane"}
  }
}

這個操作類似於 sql 中的:

where address like "%mill lane%"

上面這些 match 操作都是大小寫不敏感的。

關於 match 和 match_phrase 的篩選方式這裡只做一個示例,在後面我會單開一篇筆記詳細介紹其用法,針對 text 型別和 keyword 型別的欄位。

5、多條件查詢

多條件,就是與或非連線操作,類似於 sql 中的 and、or、not,對應在 es 中就是 must,should,must_not

在 es 中,每個連線操作都是一個陣列,用於連線多個條件操作,示例如下:

GET /bank/_search
{
  "query": {
    "bool": {
      "should": [
        {"match": {"age": 24}},
        {"match": {"age": 25}}
      ],
      "must_not": [
        {"match": {"gender": "M"}}
      ]
    }
  }
}

可以看到,與或非的操作我們是在 query 的 bool 這個 key 的下一級,這個查詢對應的 sql 的查詢是:

where (age = 24 or age = 25) and gender != "M";

6、大小於過濾

在 es 中,大小於的過濾操作是複雜一點的,也在 bool 這個 key 下一級,用到 filter 和 range 關鍵字

大小於的關鍵字和 Django 裡的是一樣的用到 gt, gte, lt, lte 這幾個

比如我們要搜尋 age 的範圍在 21 到 23 之間的包括 21 和 23 的資料

GET /bank/_search
{
  "query": {
    "bool":{
      "filter": {
        "range": {
          "age": {
            "gte": 21,
            "lte": 22
          }
        }
      }
    }
  }
}

上面的操作可以和與或非的操作進行並列,如果是直接搜尋大小於的操作,可以直接如下操作:

GET /bank/_search
{
  "query": {
    "range": {
      "age": {
        "gte": 10,
        "lte": 20
      }
    }
  }
}

如果想獲取更多後端相關文章,可掃碼關注閱讀:
image.png

相關文章