天天看點

elasticsearch 筆記二 之基礎查詢

這一篇筆記介紹幾種 es 的基礎查詢,非聚合查詢。

目錄如下:

  1. 資料導入
  2. 排序查詢
  3. es 中的 limit 和offset
  4. 比對字元串
  5. 比對詞組
  6. 數字精确查找
  7. es 中的或與非
  8. es 中的大小于過濾

首先,介紹一下 es 的存儲方式,是以 json 這種結構化文檔的形式存儲資料的。

es 下有很多 index,對應于 MySQL 中的 database,

每個 index 下有很多 type,對應于 MySQL 中的 table,

再往下就是一個個的 json 字段,相當于 MySQL 中的字段。

es 的操作風格很 restful,使用 GET、PUT、POST、DELETE 來實作資料的增删改查。

比如在 kibana 中使用如下指令建立一條資料:

PUT /customer/_doc/1
{
  "name": "John Doe"
}
           

然後就可以以這種類似于 url 的形式查詢這條資料:

GET /customer/_doc/1
           

1、資料導入

首先從官方文檔中下載下傳一批資料,資料位址。

如果不想去複制,在文章末尾下載下傳了該文檔。

然後在伺服器上使用 curl 指令導入該文檔:

記得檔案名為 accounts.json,且執行該指令的時候要在文檔所在檔案夾。

在 kibana 中檢視資料庫:

就可以在 index 那一欄下看到有 bank 這個 index 存在了。

2、排序查詢

指定 index 就可以進行查詢了。

首先可以使用以下語句,查詢一條資料,看看資料的結構:

GET /bank/_doc/1
           

傳回結果如下:

{
  "_index" : "bank",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "_seq_no" : 0,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "account_number" : 1,
    "balance" : 39225,
    "firstname" : "Amber",
    "lastname" : "Duke",
    "age" : 32,
    "gender" : "M",
    "address" : "880 Holmes Lane",
    "employer" : "Pyrami",
    "email" : "[email protected]",
    "city" : "Brogan",
    "state" : "IL"
  }
}
           

在傳回的結果裡,

_index 表示是所在的 索引名,

_type 表示所在的表名,

_source 表示的是傳回的源資料結果。

接下來我們對所有資料進行查詢,且對 balance 和 account_number 進行排序:

GET /bank/_search
{
  "query": {"match_all": {}},
  "sort": [
    {"balance": "desc"},
    {"account_number": "asc"}
  ]
}
           

語句裡的 query 下是 查詢的條件,

sort 是一個 list,裡面包含一至多個字段,用來排序,asc 是升序,desc 是降序。

3、es 中的 limit 和offset

在每次查詢傳回的結果中,如果不指定 size 字段,則會預設傳回最多十條資料。

es 中對應于 MySQL 中的 limit 和 offset 字段是 from 和 size。

from 從 0 開始取值。

GET /bank/_search
{
  "query": {"match_all": {}},
  "sort": [
    {"balance": "desc"},
    {"account_number": "asc"}
  ],
  "from": 1,
  "size": 2
}
           

4、比對字元串

比如想查詢資料中 address 字段包含 lane 或者 street 的資料,MySQL 中文法大緻是:

在 es 中使用的文法如下:

GET /bank/_search
{
  "query": {
    "match": {
      "address": "lane street"
    }
  },
  "size": 40
}
           

為了看到字段中包含 street 資料,這裡将 size 定為了 40,因為預設隻有十條。

5、比對詞組

比對詞組的說法可能不太準确,前面我們通過 空格 将兩個待選的關鍵詞分開,表示滿足這兩者之一即可。

而如果我們想要完整比對一個詞組,比如官方文檔示例中的 “mill lane”,則可以使用 match_phrase。

GET /bank/_search
{
  "query": {
    "match_phrase": {
      "address": "mill lane"
    }
  }
}
           

在 MySQL 中,文法大緻是:

以上的比對都是大小寫不敏感的,也就是比對的結果中,不區分大小寫。

如果想要設定大小寫敏感,等我回頭看到了方法再補上。

6、數字精确查找

比如想要在資料中找到 age 字段值為 35 的資料:

GET /bank/_search
{
  "query": {
    "match": {
      "age": 35
    }
  }
}
           

7、es 中的與或非

在 es 中的 與或非 分别是 must、should、must_not。

如果是兩者 或者 三者 共存,則使用 bool 将其連接配接在一起。

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

每一個 must 或者 must_not 都是一個 list,用于比對多個條件。

8、es 中的大小于過濾

es 中的大小于過濾條件,使用 filter 和 range 關鍵字,其中,filter 在組合條件中與 must 等同級。

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

繼續閱讀