ElasticSearch - 基本操作

王谷雨發表於2024-03-20

前言

本文記錄 ES 的一些基本操作,就是對官方文件的一些整理,按自己的習慣重新排版,湊合著看。官方的更詳細,建議看官方的。

下文以 books 為索引名舉例。

新增

新增單個文件 (沒有索引會自動建立)

POST books/_doc
{"name": "Snow Crash", "author": "Neal Stephenson", "release_date": "1992-06-01", "age": 18}

不指定 id,會隨機生成,如果需要指定 id,使用 POST books/_doc/id

還可以使用 put 的方式新增,例入 POST books/_doc/id,這種方式必須帶 id,否則會報錯

以上兩種方式,如果帶上了 id,就是不存在就插入,存在舊更新

更新

總結 (有三種方式):

  • POST 更新
    • 如果 URL 帶 _update,更新前會對比新舊資料,如果新舊資料完全相同,將不會進行任何操作 noop,不會影響序列號、版本號資訊。
    • 如果 URI 不帶 _update,不會檢查原資料,都會顯示 updated
  • PUT 更新
    • 路徑沒法帶 _update,每次都會更新顯示 updated

例如有原資料

{
	"name": "zhangsan",
	"age": 18
}

POST 訪問:(路徑帶_update)

需要在引數外套一層 doc,這種方式不影響其他欄位

POST /books/_update/1
{
    "doc": {
        "name": "lisi"
    }
}

// 執行之後原資料變成
{
	"name": "lisi",
	"age": 18
}

POST 訪問:(路徑不帶_update)

和帶 id 新增的語法是一樣的,不存在就是插入,存在就是更新。這種方式會清空其他欄位

POST /books/_doc/1
{
    "name": "lisi"
}

// 執行之後原資料變成
{
	"name": "lisi"
}

PUT 訪問:(路徑不能帶_update)

效果同第 2 點

PUT /books/_doc/1
{
    "name": "lisi"
}

刪除

DELETE /books/_doc/1

POST /books/_delete_by_query
{查詢條件...}

搜尋

官方例項資料:account. json

使用 [Bulk API](Bulk API | Elasticsearch Guide [8.12] | Elastic) 來批次插入,沒有安裝 kibana 也可以用 postman 匯入

如果插入記錄搜尋不到,可能是索引未來得及重新整理,可以手動觸發

POST /article/_refresh

根據 id 獲取文件

// 獲取帶後設資料的
GET /bank/_doc/1
// 獲取不帶後設資料的
GET /bank/_source/1
// 判斷文件是否存在
HEAD /bank/_doc/1

使用 HEAD 只會返回 {} 空物件,可以根據請求是否 404 判斷文件是否存在

_search 命令搜尋

注意:如果你用 es-client 連線的 es,請將 GET 換成 POST,否則查詢無效

原因是 GET 請求沒有帶上 body 引數

預設只會返回最先匹配到的 10 條文件

GET /bank/_search

返回結果:

took:檢索花費時間,單位毫秒(從節點收到查詢到將資料返回客戶端之前)

timed_out: 布林型別,檢索是否超時

hits: 命中的記錄

total.value: 總記錄的數量

hits.total: 所有命中的記錄

搜尋全部

GET /bank/_search
{
    "query": {
        "match_all": {}
    }
}

排序

Sort search results | Elasticsearch Guide [8.12] | Elastic

GET /bank/_search
{
    "sort": [
        {
            "account_number": "desc"
        },
        {
            "balance": { // 兩種寫法都行
                "order": "asc"
            }
        }
    ]
}

sort :排序條件,先對 account_number 降序,如果 account_number 相同,再對 balance 升序

其他排序引數

GET /bank/_search
{
    "sort": [
        {
            "arr": {
                "order": "desc", // 排序
                "mode": "min", // 排序模式
                "missing": "_last" // 缺失值處理
            }
        }
    ]
}

排序模式

用於對陣列或多值欄位排序。比如有資料如下

{
    "age": 25,
    "arr": [
        11000,
        23234
    ]
}

arr 欄位就是多值欄位。

升序排序的預設排序模式是 min 。預設的降序排序模式是 max

mode 說明
min 選擇最低值
max 選擇最高值
sum 總和作為排序值
avg 平均值作為排序值
median 中位數作為排序值

缺失值處理

顧名思義,就是排序時,沒有該欄位的文件排前面還是排後面。

missing 值可以設定為 _last_first,預設為 _last

分頁

Paginate search results | Elasticsearch Guide [8.12] | Elastic

查詢方式 資料量 實時查詢 排序 跳頁 適用場景
form+size 淺分頁 支援 支援 支援 實時查詢,跳頁查詢
scroll 標準方式 不支援 支援 不支援 深度分頁,有序的批次查詢
scroll_scan 滾動掃描 不支援 不支援 不支援 深度分頁,無需的批次查詢
search_after 分頁 支援 支援 不支援 深度分頁,資料批次匯出

from + size

預設返回前 10 個結果。可以使用 from 和 size 引數,from 定義要跳過的命中數,預設 0,size 是返回的最大命中數。類比 mysql 中的 limit 0,10

預設情況下,無法使用 fromsize 來翻閱超過 10,000 個匹配項。也就是前 10000 條資料可以用這種方式分頁。如果資料太多,請使用search_after

GET /bank/_search
{
    "from": 0,
    "size": 10
}

search_after

注意:搜尋必須指定排序欄位,否則獲取不到 search_after 需要的引數。

使用步驟:
一、第一頁不需要使用 search_after

// 查詢
GET /bank/_search
{
    "sort": [ // 必須指定排序欄位
        "account_number",
        "age"
    ]
}

// 響應
{
    ...
    "hits": {
        ...
        "hits": [
            {
                ...
                "sort": [ 0, 29]
            }
        ]
    }
}

第二頁的搜尋,就帶上前一頁的 hits.sort 中的引數

GET /bank/_search
{
	"search_after": [0, 29],
    "sort": [ // 必須指定排序欄位
        "account_number",
        "age"
    ]
}

TODO PIT

A 查詢資料,B 同時在插入資料,為了解決 A 兩次查詢的資料不一致,可以使用 point int time

檢索選定的欄位

Retrieve selected fields from a search | Elasticsearch Guide [8.12] | Elastic

關鍵詞 fields,可以指定返回欄位和格式

搜尋 API

Query DSL | Elasticsearch Guide [8.12] | Elastic

Search API | Elasticsearch Guide [8.12] | Elastic

query 和 filter

query 就是普通的查詢,會計算分數。

filter 不會計算分數,es 還會自動快取常用的過濾器提高效能

說明:Query and filter context | Elasticsearch Guide [8.12] | Elastic

用法:Boolean query | Elasticsearch Guide [8.12] | Elastic

複合查詢

Compound queries | Elasticsearch Guide [8.12] | Elastic

全文查詢

intervals 文字靈活查詢

Intervals query | Elasticsearch Guide [8.12] | Elastic

允許使用者精確控制查詢詞在文件中出現的先後關係,實現了對 terms 順序、terms 之間的距離以及它們之間的包含關係的靈活控制

match 模糊查詢

Match query | Elasticsearch Guide [8.12] | Elastic

對基本型別,是精確匹配(比如 long、日期等)。對字串是模糊查詢,對查詢的值分詞,對分詞的結果一一進入倒排索引去匹配

GET /ft/_search
{
    "query": {
        "match" : {
            "my_text":{
                "query": "my when",
                "operator": "or"
            }
        }
    }
}

解釋:查詢 my_text 欄位中包含 my 或者 when 的文件。

query: 需要查詢的內容

operator:預設是 or,如果改成 and,就需要 my_text 中同時包含 when 和 my

analyzer:分詞器,預設使用欄位的分詞器

prefix 字首查詢

GET /ft/_search
{
    "query": {
        "prefix": {
            "my_text": {
                "value": "favo"
            }
        }
    }
}

匹配 my_text 中以 favo 開頭的,注意是不能分詞的,也就是 my fa 查不到 cold my favourite food,但是用 favo 可以找到

match_bool_prefix 分詞字首查詢

prefix 不能分詞,那麼 match_bool_prefix 就來了

GET /ft/_search
{
    "query": {
        "match_bool_prefix": {
            "my_text": {
                "query": "quick brown f"
            }
        }
    }
}

解釋:先分詞,最後一個詞按字首處理,前面的詞語直接匹配,只要有一個命中就可以

匹配 quick brown foxtwo quick brown ferretsthe fox is quick and brown

match_phrase 短語匹配查詢

顧名思義,match 會分詞,match_phrase 不會分詞

GET /ft/_search
{
    "query": {
        "match_phrase": {
            "my_text": {
                "query": "wo shi"
            }
        }
    }
}

match_phrase_prefix 短語字首匹配查詢

GET /ft/_search
{
  "query": {
    "match_phrase_prefix": {
      "my_text": {
        "query": "quick brown f"
      }
    }
  }
}

與 match_bool_prefix 的區別就是不分詞,匹配 quick brown foxtwo quick brown ferrets,不匹配 the fox is quick and brown

combined_fields 組合多欄位查詢

Combined fields | Elasticsearch Guide [8.12] | Elastic

這個有點不太理解。

GET /ft/_search
{
    "query": {
        "combined_fields": {
            "query": "ren shui",
            "fields": [
                "title",
                "my_text"
            ],
            "operator": "and"
        }
    }
}

解釋:效果類似於將 title 和 my_text 兩個欄位合併成一個,再執行查詢

注意,我把 operator 改成 and 了,但是隻要 title 和 my_text 組合起來,包含了 ren 和 shui 就能命中

multi_match 多欄位查詢

Multi-match query | Elasticsearch Guide [8.12] | Elastic

在 match 查詢的基礎上,允許多欄位查詢

GET /ft/_search
{
    "query": {
        "multi_match": {
            "query": "ren shui",
            "fields": [
                "title",
                "my_text"
            ],
            "operator": "and"
        }
    }
}

解釋:我把 operator 改成了 and,那麼需要 title 同時包含 ren 和 shui 兩個詞,或者 my_text 同時包含兩個詞,才能命中。和 combined_fields 有區別的。

總結

沒啥好總結的,吐槽一句,官方文件對新手不太友好。新手需要的是快速使用,怎麼調 api

參考

【ElasticSearch(四)】PUT&POST更新資料、DELETE刪除資料、_bulk批次操作 - musecho - 部落格園 (cnblogs.com)

相關文章