1. 程式人生 > >ES (Elasticsearch)入門指南

ES (Elasticsearch)入門指南

 

簡介

ES=elaticsearch簡寫, Elasticsearch是一個開源的高擴充套件的分散式全文檢索引擎,它可以近乎實時的儲存、檢索資料;本身擴充套件性很好,可以擴充套件到上百臺伺服器,處理PB級別的資料。 本質上是一個分散式nosql資料庫,允許多臺伺服器協同工作,每臺伺服器可以執行多個 Elastic 例項。單個 Elastic 例項稱為一個節點(node)。一組節點構成一個叢集(cluster)。

概念介紹

關係資料庫(mysql) ⇒ 資料庫 ⇒ 表 ⇒ 行 ⇒ 列(Columns)

Elasticsearch             ⇒ 索引 ⇒ 型別 ⇒ 文件 ⇒ 欄位(Fields)

index: es裡的index相當於一個數據庫,每個 Index (即資料庫)的名字必須是小寫。 

type: 相當於資料庫裡的一個表。 

id: 唯一,相當於主鍵PUT資料的時候需要指定id。 

node:節點是es例項,一臺機器可以執行多個例項,但是同一臺機器上的例項在配置檔案中要確保http和tcp埠不同。 

cluster:代表一個叢集,叢集中有多個節點,其中有一個會被選為主節點,這個主節點是可以通過選舉產生的,主從節點是對於叢集內部來說的。 

shards:代表索引分片,es可以把一個完整的索引分成多個分片,這樣的好處是可以把一個大的索引拆分成多個,分佈到不同的節點上,構成分散式搜尋。分片的數量只能在索引建立前指定,並且索引建立後不能更改。 

replicas:代表索引副本,es可以設定多個索引的副本,副本的作用一是提高系統的容錯性,當個某個節點某個分片損壞或丟失時可以從副本中恢復。二是提高es的查詢效率,es會自動對搜尋請求進行負載均衡。

mapping  在 Elasticsearch  中的作用就是約束,類似於mysql中的表的約束。

ElasticSearch 客戶端程式除了Java 使用TCP的方式連線ES叢集以外,其他的語言基本上都是使用的Http的方式。眾所周知,ES 客戶端預設的TCP埠為9300,而HTTP預設埠為9200。elasticsearch-hadoop 使用的就是HTTP的方式連線的ES叢集。

域資料型別:

mapping

Mapping)相當於資料表的表結構。ElasticSearch中的對映(Mapping)用來定義一個文件,可以定義所包含的欄位以及欄位的型別、分詞器及屬性等等,對映可以分為動態對映和靜態對映。 
(1)動態對映 
我們知道,在關係資料庫中,需要事先建立資料庫,然後在該資料庫例項下建立資料表,然後才能在該資料表中插入資料。而ElasticSearch中不需要事先定義對映(Mapping),文件寫入ElasticSearch時,會根據文件欄位自動識別型別,這種機制稱之為動態對映。

(2)靜態對映 
當然,在ElasticSearch中也可以事先定義好對映,包含文件的各個欄位及其型別等,這種方式稱之為靜態對映。

ES 6.3 mapping 引數說明

   "type"        : "text", #是資料型別一般文字使用text(可分詞進行模糊查詢);keyword無法被分詞(不需要執行分詞器),用於精確查詢
   "format"     : "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis" ,#格式化 此引數代表可接受的時間格式 3種都接受
   "analyzer"  : "ik_max_word", #指定分詞器,一般使用最大分詞:ik_max_word
   "index"       : true, #該欄位是否會被索引和可查詢 預設true 不分詞是:not_analyzed ,設定成  no,欄位將不會被索引
    "store"       : true, #預設情況false,其實並不是真沒有儲存,_source欄位裡會儲存一份原始文件。
    # 在某些情況下,store引數有意義,比如一個文件裡面有title、date和超大的content欄位,如果只想獲取title和date
  "boost"         : 1.5, #欄位權重;用於查詢時評分,關鍵欄位的權重就會高一些,預設都是1;另外查詢時可臨時指定權重
 "normalizer"   : "normalizer_name", #欄位標準化規則;如把所有字元轉為小寫;具體如下舉例
  "coerce"        : true, #清理髒資料:1,字串會被強制轉換為整數 2,浮點數被強制轉換為整數;預設為true

更新mapping

es中建立後的mapping不可修改,但是可以新增新欄位
新增新欄位:

PUT /my_index/_mapping/my_type
{
  "properties": {
       "new_field_name": {
           "type":     "string"
       }
   }
}

賦值:

POST my_index/_update_by_query
{
  "script": {
    "lang": "painless",
    "inline": "ctx._source.new_field_name= '02'"
  }
}

pretty

在任意的查詢字串中增加pretty引數,會讓Elasticsearch美化輸出(pretty-print)JSON響應以便更加容易閱讀。
_source欄位不會被美化,它的樣子與我們輸入的一致。
ES資料結構

index定義欄位的分析型別以及檢索方式

  • 如果是no,則無法通過檢索查詢到該欄位;
  • 如果設定為not_analyzed則會將整個欄位儲存為關鍵詞,常用於漢字短語、郵箱等複雜的字串;
  • 如果設定為analyzed則將會通過預設的standard分析器進行分析

store定義了欄位是否儲存

在ES中原始的文字會儲存在_source裡面(除非你關閉了它)。預設情況下其他提取出來的欄位都不是獨立儲存的,是從_source裡面提取出來的。當然你也可以獨立的儲存某個欄位,只要設定store:true即可。獨立儲存某個欄位,在頻繁使用某個特殊欄位時很常用。而且獲取獨立儲存的欄位要比從_source中解析快得多,而且額外你還需要從_source中解析出來這個欄位,尤其是_source特別大的時候。不過需要注意的是,獨立儲存的欄位越多,那麼索引就越大;索引越大,索引和檢索的過程就會越慢....

string

字串型別,es中最常用的類型別: 注意:5.X以上版本沒有string型別了,換成了text

把string欄位設定為了過時欄位,引入text,keyword欄位,這兩個欄位都可以儲存字串使用,但建立索引和搜尋的時候是不太一樣的

keyword:儲存資料時候,不會分詞建立索引

text:儲存資料時候自動分詞並生成索引(這是智慧的,但在有些欄位裡面是沒用的,所以對於有些欄位使用text則浪費了空間)

store儲存

true 獨立儲存 false(預設)不儲存,從_source中解析

Numeric

數值型別,注意numeric並不是一個型別,它包括多種型別,比如:long,integer,short,byte,double,float,每種的儲存空間都是不一樣的,一般預設推薦integer和float。官方文件參考

重要的引數:

index分析    not_analyzed(預設) ,設定為該值可以保證該欄位能通過檢索查詢到

store儲存  true 獨立儲存    false(預設)不儲存,從_source中解析

date

日期型別,該型別可以接受一些常見的日期表達方式,官方文件參考

重要的引數:

index分析  not_analyzed(預設) ,設定為該值可以保證該欄位能通過檢索查詢到

store儲存  true 獨立儲存   false(預設)不儲存,從_source中解析

format格式化

strict_date_optional_time||epoch_millis(預設)

你也可以自定義格式化內容,比如

"date": {

  "type":   "date",

  "format": "yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"

}

boolean

布林型別,所有的型別都可以標識布林型別,參考官方文件

False: 表示該值的有:false, "false", "off", "no", "0", "" (empty string), 0, 0.0

True: 所有非False的都是true

重要的引數:

index分析 not_analyzed(預設) ,設定為該值可以保證該欄位能通過檢索查詢到 

store儲存  true 獨立儲存  false(預設)不儲存,從_source中解析

指令總結

我講從索引(資料庫)→型別(表)→文件(行)→屬性(欄位)一一介紹相關的指令

請求型別

Http請求內容:

PUT /customer?pretty

GET /_cat/indices?v

Curl命令

curl -XPUT ‘localhost:9200/customer?pretty&pretty’

curl -XGET ‘localhost:9200/_cat/indices?v&pretty’

POST和PUT的區別

POST不用加具體的id,它是作用在一個集合資源之上的(/uri),而PUT操作是作用在一個具體資源之上的(/uri/xxx)。

在ES中,如果不確定document的ID(documents具體含義見下),那麼直接使用POST對應uri( “POST /website/blog” ),ES可以自己生成不會發生碰撞的UUID當做ID;如果確定document的ID,即自己設定的ID,使用PUT即可,比如 “PUT /website/blog/123”,那麼執行建立或修改(修改時_version版本號提高1) 

1.每個 Index 所包含的 Type

 curl  -H "Content-Type: application/json" 'localhost:9200/_mapping?pretty=true'

2.建立一個索引

curl -XPUT 'localhost:9200/sqlcommand?pretty'

或  5.5 以後儘量使用下面的方式

curl -XPUT -H 'Content-Type: application/json' 'localhost:9200/megacorp?pretty'(5.5以後版本)

返回資訊 代表建立成功

{
  "acknowledged" : true,
  "shards_acknowledged" : true
}

3.顯示所有索引

curl -XGET -H 'Content-Type: application/json' 'localhost:9200/_cat/indices?v'

4.刪除索引

curl -XDELETE 'localhost:9200/sqlcommand?pretty'

5.在對應的索引中建立文件和type已經定義mapping

curl -H "Content-Type: application/json" -PUT  "http://127.0.0.1:9200/sqltest/infotest/_mapping?pretty" -d ' 
{
    "infotest": { 
             "properties": {
                          "application_id": {
                    "type": "keyword"
                },
                           "session_id": {
                    "type": "keyword"
                },
                         "user_ip_address": {
                    "type": "keyword"
                },
                         "logger_type": {
                    "type": "keyword"
                },
                         "mryxblg_command_monitoring": {
                    "type": "keyword"
                }
              }
            }
    }'

匯入資料

curl -H "Content-Type: application/json" -XPOST   'http://127.0.0.1:9200/productx/product/1' -d '
{
  "title": "物品",
  "description": "電腦",
  "price": 89.0
  "onSale": true
  "type": 2
  "createDate": 2018
}' 

注意:PUT一定要大寫     -d之前,必需要空格

檢視索引的type

curl -X GET 'localhost:9200/sql_command/_mapping'

6.檢索文件

普通檢索

curl -XGET  -H 'Content-Type: application/json' 'http://localhost:9200/megacorp/employee/1'

輕量檢索

curl -XGET  -H 'Content-Type: application/json' 'http://localhost:9200/megacorp/employee/_search'

檢索部分內容

curl -XGET  -H 'Content-Type: application/json' 'http://localhost:9200/megacorp/employee/1?_source=first_name,last_name'

只得到源的內容

curl -XGET  -H 'Content-Type: application/json' 'http://localhost:9200/megacorp/employee/1?_source'

按條件搜尋

curl -XGET  -H 'Content-Type: application/json' 'http://localhost:9200/megacorp/employee/_search?q=last_name:Smith'

Q =表示匹配全部文件 *   排序=年齡表示按照年齡資訊排序 ASC表示升序

可以不加引數,查詢全部文件

curl -XGET 'localhost:9200/megacorp/_search?pretty'

 

{
  "took" : 5,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : null,
    "hits" : [
      {
        "_index" : "customer",
        "_type" : "external",
        "_id" : "1",
        "_score" : null,
        "_source" : {
          "name" : "Zhao1"
        },
        "sort" : [
          9223372036854775807
        ]
      }
    ]
  }
}

使用檢索表示式

curl -XGET  -H 'Content-Type: application/json' 'http://localhost:9200/megacorp/employee/_search?pretty' -d '
{
    "query" : {
        "match" : {
            "last_name" : "Smith"
        }
    }
}'

複雜檢索

curl -XGET  -H 'Content-Type: application/json' 'http://localhost:9200/megacorp/employee/_search?pretty' -d '
{
    "query" : {
        "bool": {
            "must": {
                "match" : {
                    "last_name" : "smith" 
                }
            },
            "filter": {
                "range" : {
                    "age" : { "gt" : 30 } 
                }
            }
        }
    }
}'

批量檢索(multi-get或者mget API)

mget API要求有一個docs陣列作為引數,每個元素包含需要檢索文件的元資料,包括_index,_type和_id。如果你想檢索一個或者多個特定的欄位,那麼你可以通過_source引數來指定這些欄位的名字:

curl -XGET -H 'Content-Type: application/json' 'http://localhost:9200/_mget?pretty' -d '
{
   "docs" : [
      {
         "_index" : "megacorp",
         "_type" :  "employee",
         "_id" :    2
      },
      {
         "_index" : "megacorp",
         "_type" :  "employee",
         "_id" :    1
      }
   ]
}'

如果想檢索的資料都在相同的_index中(甚至相同的_type中),則可以在URL中指定預設的/ _index或者預設的

文件是否存在

curl  -i -XHEAD  -H 'Content-Type: application/json' 'http://localhost:9200/megacorp/employee/4'

刪除文件

curl -XDELETE  -H 'Content-Type: application/json' 'http://localhost:9200/megacorp/employee/4'

成功返回200,找不到是404,版本會加1(即使是虛假),_版本值仍然會增加。這是Elasticsearch內部記錄本的一部分,用來確保這些改變在跨多節點時以正確的順序執行)

刪除全部文件

curl -XPOST -H 'Content-Type: application/json' 'http://localhost:9200/megacorp/employee/_delete_by_query?conflicts=proceed' -d '
{
  "query": {
    "match_all": {}
  }
}'