Elasticsearch操做實踐手冊|建議收藏篇

我是啤酒就辣條。

但行好事,莫問前程。html

官方爲咱們提供了多種語言操做Elasticsearch的API,能夠很方便的在項目中操做。學習利用原生請求操做Elasticsearch,方便維護數據庫,還能加快學習使用不一樣語言的API。正則表達式

本博客使用kibana發起請求,使用kibana能夠查看快捷鍵。數據庫

索引操做

建立索引

建立索引使用PUT請求,後面跟上索引名稱就行了,因爲7.x默認type爲_doc,因此後面沒必要跟上type了。在PUT簡單請求同時,能夠加上JSON請求體,進行復雜建立。json

PUT /user
{
  "settings": {
    "index": {
      "number_of_shards": 3,  
      "number_of_replicas": 2 
    }
  },
  "mappings": {
    "properties": {
      "name": { "type": "text" },
      "age": {"type": "short"},
      "city":{"type": "keyword"}
    }
  }
}

建立索引user,能夠經過參數setting設置分片和副本數,經過number_of_shards設置一共有3個分片,經過number_of_replicas給每一個分片設置2個副本,默認不指定的話,這兩個參數都是1。經過mappings規定文檔各個Filed插入類型。此外,還能夠設置aliases字段,給索引建立別名,這樣不只能夠經過別名訪問該索引,還能夠定義查詢條件、指定查詢分片等等,詳情請參考數組

刪除索引

刪除索引,使用DELETE請求。瀏覽器

DELETE /user

查看索引

查看索引,使用GET請求,能夠查看索引設置的參數。緩存

刪除以後,我又從新添加索引,沒有設置settings,因此分片和副本都是1。app

你也能夠經過在索引後面加參數來查看某一具體參數,如:elasticsearch

GET /user/_settings
GET /user/_mappings
GET /user/_aliases

修改索引部分設置

能夠經過PUT請求修改部分索引的settings,例如,分片副本數量能夠修改,可是分片數量不能夠經過這種方式修改。ide

PUT /user/_settings
{
  "number_of_replicas": 3 
}

能夠經過以上請求,修改分片副本。

文檔操做

建立好索引,來看下文檔的增刪改查,這是平常業務用的最多的地方。

插入文檔

新增文檔使用PUTPOST請求。

PUT /<target>/_doc/<_id>

POST /<target>/_doc/

PUT /<target>/_create/<_id>

POST /<target>/_create/<_id>

target爲索引名稱,_doc爲默認type。經過前兩種請求可看出,id能夠自行指定,也能夠由ES自動生成。_create能夠保證只有當文檔不存在的時候進行插入,而_doc還能夠用於文檔更新。

POST /user/_doc/1
{
  "name":"pjjlt",
  "age":26,
  "city":"sjz"
}

更新文檔

更新文檔可使用PUT或者POST請求關鍵字,全量更新。

POST /user/_doc/1
{
  "name":"pjjlt",
  "age":3,
  "city":"sjz"
}

還能夠經過_update命令局部更新,所謂局部更新,是講請求體內不須要加入所有字段,只加入須要修改的字段就好,其餘字段不變。全量更新會替換整個文檔。

POST /user/_update/1
{
  "doc":{
    "age": 26
  }
}

此外還能夠經過腳本修改,例如將全部存在age字段的文檔,其值改爲5歲。

POST /user/_update_by_query
{
  "script": {
    "source": "ctx._source['age']=5" 
  },
  "query": {
    "bool": {
      "must": [
        {
          "exists": {
            "field": "age"
          }
        }
      ]
    }
  }
}

此外update_update_by_query字段還能夠修改Filed,例如將name修改爲name1,這塊內容使用較少,如感興趣,請參考官方文檔。

刪除文檔

刪除文檔可使用DELEETE請求,刪除指定id的文檔,也可使用_delete_by_query,刪除指定條件下的文檔。

DELETE /user/_doc/1
POST /user/_delete_by_query
{
  "query": {
    "match": {
      "name": "pjjlt"
    }
  }
}

查找文檔

查找文檔是ES操做最精彩的部分,這裏只介紹簡單的查詢,複雜查詢、聚合查詢後面會介紹。

根據id查詢某文檔。

GET /user/_doc/1

查找某索引下的所有文檔

GET /user/_search?pretty

pretty參數在瀏覽器中才會發揮做用,格式化返回json的。以上這條命令默認返回10條數據,想返回更多數據能夠添加size字段。

GET /user/_search?pretty&size=20

能夠看出,數據部分在hits裏面,Spring提供的elasticsearch客戶端會有對應的實體類,在項目中很方便的使用。下面看下這幾部分的含義。

元素 含義
took 運行查詢須要多長時間
time_out 請求是否超時
_shards 搜索了多少分片,多少成功
多少跳過,多少失敗
hits.total 總共有多少數據
hits._max_score 查詢到的文檔中,關聯度最大文檔分數
hits.hits._source 查詢到的數據
hits.hits.id 某文檔的主鍵

批量操做

批量操做是指,一批命令同時執行(減小IO),這些命令不必定是同種類型。

使用_bulk命令能夠進行文檔的批量增刪改。

POST _bulk
{ "update" : { "_index" : "user", "_id" : "1" } }
{ "doc" : {"age" : 18} }
{ "create" : { "_index" : "user", "_id" : "2" } }
{ "name" : "小明","age":32,"city":"beijing" }
{ "create" : { "_index" : "user", "_id" : "3" } }
{ "name" : "小紅","age":21,"city":"sjz" }
{ "create" : { "_index" : "user", "_id" : "4" } }
{ "name" : "mark","age":22,"city":"tianjin" }
{ "delete" : { "_index" : "user", "_id" : "4" } }

以上命令更新了id爲1文檔的年齡,新增id爲二、三、4的文檔,再刪除id爲4的文檔。

上邊的命令堆在一塊兒不方便看,下面單獨寫看,方便讀者查看。

批量新增

POST _bulk
{ "create" : { "_index" : "user", "_id" : "2" } }
{ "name" : "小明","age":32,"city":"beijing" }
{ "create" : { "_index" : "user", "_id" : "3" } }
{ "name" : "小紅","age":21,"city":"sjz" }

{ "index" : { "_index" : "user", "_id" : "4" } }
{ "name" : "mark","age":22,"city":"tianjin" }

create命令是隻有文檔不存在,纔會插入,index會判斷若是存在就更新,不存在就插入。

批量更新

POST _bulk
{ "update" : { "_index" : "user", "_id" : "1" } }
{ "doc" : {"age" : 18} }
{ "update" : { "_index" : "user", "_id" : "2" } }
{ "doc" : {"age" : 20} }

和新增同樣,update命令下一行須要緊跟這data數據。

批量刪除

POST _bulk
{ "delete" : { "_index" : "user", "_id" : "3" } }
{ "delete" : { "_index" : "user", "_id" : "4" } }

批量查找

批量查找,使用_mget關鍵字,批量查找若是不跨越索引,也具備簡寫形式。

GET /_mget
{
  "docs": [
    {
      "_index": "user",
      "_id": "1"
    },
    {
      "_index": "user",
      "_id": "2"
    }
  ]
}

# 還能夠簡寫形式
POST /user/_mget
{
  "ids": [
    "1",
    "2",
    "3"
  ]
}

DSL查詢

Elasticsearch提供了一個完整的基於JSON的查詢DSL(領域特定語言)來定義查詢。能夠將查詢DSL看做查詢的AST(抽象語法樹),它由兩種類型的子句組成: Leaf query clauses(葉查詢子句)和 Compound query clauses(複合查詢子句)

以上摘自官網,簡單來講,DSL就是將查詢條件放到JSON中,進行查詢。

Leaf query clauses在特定字段上查找特定的值,例如matchtermrange查詢等等。

Compound query clauses將葉查詢子句和其餘符合查詢子句結合起來,例如bool查詢等等。

match

match是一個標準查詢,當查詢一個文本的時候,會先將文本分詞。當查詢確切值的時候,會搜索給定的值,例如數字、日期、布爾或者被not_analyzed的字符串。
GET /user/_search
{
  "query": {
    "match": {
      "name":"小明"
    }
  }
}

上面的操做會先將「小明」分詞爲「小」、「明」(固然具體還要看你的分詞器),而後再去全部文檔中查找與之相匹配的文檔,並根據關聯度排序返回。

match_phrase

match_phrase會保留空格,match會把空格忽略。
GET /user/_search
{
  "query": {
    "match_phrase": {
      "name":"小 明"
    }
  }
}

注意,分詞是空格會給前一個元素,好比上面的字符串分子以後是,「小 」,「明」。

multi_match

多字段查詢,一個查詢條件,看全部多個字段是否有與之匹配的字段。後面咱們也可使用 should更加靈活。
GET /user/_search
{
  "query": {
    "multi_match": {
      "query":    "哈哈", 
      "fields": [ "name","city" ] 
    }
  }
}

match_all

匹配全部,並可設置這些文檔的 _score,默認 _score爲1,辣條君認爲這裏沒有計算 _score,因此速度會快不少。
GET /user/_search
{
  "query": {
    "match_all": { "boost" : 1.2 }
  }
}

boost參數能夠省略,默認是1。

term

term是一種徹底匹配,主要用於精確查找,例如數字、ID、郵件地址等。
GET /user/_search
{
  "query": {
    "term": {
      "age": 18
    }
  }
}

terms

terms是term多條件查詢,參數能夠傳遞多個,以數組的形式表示。
GET /user/_search
{
  "query": {
    "terms": {
      "age":[18,21]
    }
  }
}

wildcard

通配符,看示例容易理解,通配符能夠解決分詞匹配不到的問題,例如'haha' 能夠經過'*a'匹配。
GET /user/_search
{
  "query": {
    "wildcard": {
      "name":"*a"
    }
  }
}

exists

查看某文檔是否有某屬性,返回包含這個 Filed的文檔。
GET /user/_search
{
  "query": {
    "exists": {
      "field": "name"
    }
  }
}

fuzzy

返回與查詢條件相同或者類似的匹配內容。
GET /user/_search
{
  "query": {
    "fuzzy": {
      "name":"mjjlt"
    }
  }
}

搜索條件是mjjlt,能夠搜出來name爲pjjlt的文檔。這個操做是否是在百度的時候常常見到呢?

ids

多id查詢,這個id是主鍵id,即你規定或者自動生成那個。
GET /user/_search
{
  "query": {
    "ids": {
      "values":[1,2,3]
    }
  }
}

prefix

前綴匹配
GET /user/_search
{
  "query": {
    "prefix": {
      "name":"pj"
    }
  }
}

range

範圍匹配。參數能夠是 gt(大於)、 gte(大於等於)、 lt(小於)、 lte(小於等於)
GET /user/_search
{
  "query": {
    "range": {
      "age":{
          "gt":1,
          "lt":30
      }
    }
  }
}

regexp

正則匹配。value是正則表達式,flags是匹配格式,默認是ALL,開啓全部。更多格式 請戳
GET /user/_search
{
  "query": {
    "regexp": {
      "name":{
          "value": "p.*t",
          "flags": "ALL"
      }
    }
  }
}

bool

bool 能夠用來組合其餘子查詢。其中常包含的子查詢包含:must、filter、should、must_not

must

must內部的條件必須包含,內部條件是and的關係。如查看全部name中包含「小」而且age是32的用戶文檔。

GET /user/_search
{
  "query": {
    "bool" : {
      "must": [
        {"term" : { "name" : "小" }},
        {"term" : { "age" : 32 }}
      ]
    }
  }
}

filter

filter是文檔經過一些條件過濾下,這是四個關鍵詞中惟一和關聯度無關的,不會計算_score,常用的過濾器會產生緩存。

GET /user/_search
{
  "query": {
    "bool" : {
      "filter": {
        "term" : { "name" : "小" }
      }
    }
  }
}

對比兩張圖能夠看出,filter並無計算_score,搜索速度較快。

must_not

這個和must相反,文檔某字段中必定不能包含某個值,至關於「非」。

should

should能夠看作or的關係,例以下面查詢name包含"小"或者年齡是18歲的用戶。

GET /user/_search
{
  "query": {
    "bool" : {
      "should": [
        {"term" : { "name" : "小" }},
        {"term" : { "age" : 18 }}
      ]
    }
  }
}

聚合查詢

Elasticsearch除全文檢索功能外提供的針對Elasticsearch數據作統計分析的功能。能夠查詢某組數據的最大最小值,分組查詢某些數據。

  • Metric(指標): 指標分析類型,如計算最大值、最小值、平均值等等 (對桶內的文檔進行聚合分析的操做)
  • Bucket(桶): 分桶類型,相似SQL中的GROUP BY語法 (知足特定條件的文檔的集合)
  • Pipeline(管道): 管道分析類型,基於上一級的聚合分析結果進行在分析

Metric(指標)數據

經常使用數學操做

這裏經常使用的數學操做有 min(最小)、 max(最大)、 sum(和)、 avg(平均數)。注意這些操做只能輸出一個分析結果。使用方式大同小異。
GET /user/_search
{
    "aggs" : {
        "avg_user_age" : 
        { 
          "avg" : { "field" : "age" } 
        }
    }
}

以上示例查詢全部用戶的平均年齡,返回全部文檔和聚合查詢結果。aggs是聚合查詢關鍵詞,avg_user_age是查詢名稱,用戶能夠自行定義。

cardinality

計算某字段去重後的數量
GET /user/_search
{
    "aggs" : {
        "avg_user" : 
        { 
          "cardinality" : { "field" : "age" } 
        }
    }
}

能夠計算,全部文檔中年齡不相同的文檔個數。

percentiles

對指定字段的值按從小到大累計每一個值對應的文檔數的佔比,返回指定佔比比例對應的值。

默認統計百分比爲[ 1, 5, 25, 50, 75, 95, 99 ]

GET /user/_search
{
    "aggs" : {
        "avg_user" : 
        { 
          "percentiles": { "field" : "age" } 
        }
    }
}

# 返回值(省略文檔部分,只分析結果部分)
  "aggregations" : {
    "avg_user" : {
      "values" : {
        "1.0" : 12.0,
        "5.0" : 12.0,
        "25.0" : 20.25,
        "50.0" : 29.0,
        "75.0" : 57.75,
        "95.0" : 123.0,
        "99.0" : 123.0
      }
    }
  }

能夠看出,前1%的用戶小於12歲,5%的用戶小於12歲,25%的用戶小於20.25歲,50%的用戶小於29歲。。。

percentile_ranks

percentiles是經過百分比求出文檔某字段,percentile_ranks是給定文檔中的某字段求百分比。
GET /user/_search
{
    "aggs" : {
        "avg_user" : 
        { 
          "percentile_ranks": 
            { 
              "field" : "age",
              "values" : [18, 30]
            } 
        }
    }
}

# 返回值(省略文檔部分,只分析結果部分)
  "aggregations" : {
    "avg_user" : {
      "values" : {
        "18.0" : 18.51851851851852,
        "30.0" : 54.44444444444445
      }
    }
  }

能夠看出,小於等於18歲的用戶有18.52%,小於等於30歲的用戶有54.4%。

top_hits

top_hits能夠獲得某條件下top n的文檔。
GET /user/_search
{
  "aggs": {
    "avg_user" : {
      "top_hits": {
          "sort": [
          {
            "age": {
              "order": "asc"
            }
          }
        ],
        "size": 1
      }
    }
  },
  "size": 0
}

取年齡最小的那一個。

Bucket(桶)

相似於分組的概念。

terms

根據給定的filed分組,返回每組多少文檔。
GET /user/_search
{
    "aggs" : {
        "avg_user" : 
        { 
          "terms": {
                  "field": "city"
                }
        }
    }
}

以上根據城市分組,看每一個城市有多少用戶。

ranges

根據區間分組
GET /user/_search
{
  "aggs": {
    "price_ranges": {
      "range": {
        "field": "age",
        "ranges": [
          { "to": 20 },
          { "from": 20, "to": 30 },
          { "from": 30 }
        ]
      }
    }
  }
}

能夠查看每一個年齡層的用戶數量。

還有些頗有趣的指令,例如[IP range]能夠根據ip段區間分組,之後用到再說吧,但願文本能夠不段更新的說...

相關文章
相關標籤/搜索