Elasticsearch簡單介紹
Elasticsearch (ES)是一個基於Lucene構建的開源、分布式、RESTful 接口全文搜索引擎。Elasticsearch 還是一個分布式文檔數據庫,其中每個字段均是被索引的數據且可被搜索,它能夠擴展至數以百計的服務器存儲以及處理PB級的數據。它可以在很短的時間內在存儲、搜索和分析大量的數據。它通常作為具有復雜搜索場景情況下的核心發動機。es是由java語言編寫的。
Elasticsearch就是為高可用和可擴展而生的。可以通過購置性能更強的服務器來完成。
Elasticsearch 應用場景
大型分布式日志分析系統 ELK elasticsearch(存儲日志)+logstash(收集日志)+kibana(展示數據)
大型電商商品搜索系統、網盤搜索引擎等,主要用於大數據收集。
Elasticsearch優勢
橫向可擴展性:只需要增加台服務器,做一點兒配置,啟動一下Elasticsearch就可以並入集群。
分片機制提供更好的分布性:同一個索引分成多個分片(sharding), 這點類似於HDFS的塊機制;分而治之的方式可提升處理效率。
高可用:提供復制( replica) 機制,一個分片可以設置多個復制,使得某台服務器在宕機的情況下,集群仍舊可以照常運行,並會把服務器宕機丟失的數據信息復制恢復到其他可用節點上。
使用簡單:共需一條命令就可以下載文件,然后很快就能搭建一一個站內搜索引擎。
Elasticsearch存儲結構
Elasticsearch是文件存儲,Elasticsearch是面向文檔型數據庫,一條數據在這里就是一個文檔,用JSON作為文檔序列化的格式,比如下面這條用戶數據:
{
"name":"yushengjun",
"sex":0,
"age":24
}
關系數據庫 ⇒ 數據庫 ⇒ 表 ⇒ 行 ⇒ 列(Columns)
Elasticsearch ⇒ 索引(Index) ⇒ 類型(type) ⇒ 文檔(Docments) ⇒ 字段(Fields)
9200與9300端口號的區別
9300端口: ES節點之間通訊使用,是TCP協議端口號,ES集群之間通訊端口號。
9200端口: ES節點 和 外部 通訊使用,暴露ES RESTful接口端口號。瀏覽器訪問時,例如:http://192.168.0.110:9200/myindex/user/3
倒排索引
正向索引
正排表是以文檔的ID為關鍵字,表中記錄文檔中每個字的位置信息,查找時掃描表中每個文檔中字的信息直到找出所有包含查詢關鍵字的文檔。
這種組織方法在建立索引的時候結構比較簡單,建立比較方便且易於維護;因為索引是基於文檔建立的,若是有新的文檔加入,直接為該文檔建立一個新的索引塊,掛接在原來索引文件的后面。若是有文檔刪除,則直接找到該文檔號文檔對應的索引信息,將其直接刪除。但是在查詢的時候需對所有的文檔進行掃描以確保沒有遺漏,這樣就使得檢索時間大大延長,檢索效率低下。
盡管正排表的工作原理非常的簡單,但是由於其檢索效率太低,除非在特定情況下,否則實用性價值不大。
倒排索引
倒排表以字或詞為關鍵字進行索引,表中關鍵字所對應的記錄表項記錄了出現這個字或詞的所有文檔,一個表項就是一個字表段,它記錄該文檔的ID和字符在該文檔中出現的位置情況。
由於每個字或詞對應的文檔數量在動態變化,所以倒排表的建立和維護都較為復雜,但是在查詢的時候由於可以一次得到查詢關鍵字所對應的所有文檔,所以效率高於正排表。在全文檢索中,檢索的快速響應是一個最為關鍵的性能,而索引建立由於在后台進行,盡管效率相對低一些,但不會影響整個搜索引擎的效率。
正排索引是從文檔到關鍵字的映射(已知文檔求關鍵字),倒排索引是從關鍵字到文檔的映射(已知關鍵字求文檔)。
文檔內容:
序號 |
文檔內容 |
1 |
小俊是一家科技公司創始人,開的汽車是奧迪a8l,加速爽。 |
2 |
小薇是一家科技公司的前台,開的汽車是保時捷911 |
3 |
小紅買了小薇的保時捷911,加速爽。 |
4 |
小明是一家科技公司開發主管,開的汽車是奧迪a6l,加速爽。 |
5 |
小軍是一家科技公司開發,開的汽車是比亞迪速銳,加速有點慢 |
倒排索引會對文檔內容進行關鍵詞分詞,可以使用關鍵次直接定位到文檔內容。
單詞ID |
單詞 |
倒排列表docId |
1 |
小 |
1,2,3,4,5 |
2 |
一家 |
1,2,4,5 |
3 |
科技公司 |
1,2,4,5 |
4 |
開發 |
4,5 |
5 |
汽車 |
1,2,4,5 |
6 |
奧迪 |
1,4 |
7 |
加速爽 |
1,3,4 |
8 |
保時捷 |
2,3 |
9 |
保時捷911 |
2 |
10 |
比亞迪 |
5 |
高級查詢命令
GET _search
{
"query": {
"match_all": {}
}
}
##### 創建索引
PUT /myindex
##### 查詢索引
GET myindex
##### 創建一個文檔 /索引/類型/id
PUT /myindex/user/1
{
"name":"mingtian",
"age":24,
"sex":"男"
}
PUT /myindex/user/2
{
"name":"xiaoming",
"age":24,
"sex":"男"
}
PUT /myindex/user/3
{
"name":"校花",
"age":24,
"sex":"女"
}
PUT /myindex/user/4
{
"name":"小鳳",
"age":22,
"sex":"女"
}
PUT /myindex/user/5
{
"name":"大白",
"age":22,
"sex":"男"
}
PUT /myindex/user/6
{
"name":"Summer",
"age":20,
"sex":"男"
}
PUT /myindex/user/7
{
"name":"Sun",
"age":18,
"sex":"男"
}
#### 查詢文檔
GET /myindex/user/1
##### 刪除索引
DELETE /myindex
#### 查詢索引
GET myindex
#### 高級查詢 查詢myindex 下面所有的文檔信息
GET /myindex/user/_search
####根據多個id 查詢
GET /myindex/user/_mget
{
"ids":["1","2"]
}
#### 查詢年齡 24 的
GET /myindex/user/_search?q=24
### 查詢區間 年齡18-23之間的 TO 必須大寫
GET /myindex/user/_search?q=age[18 TO 23]
### 年齡18-23之間的、降序排列、從0條數據到第1條數據
GET /myindex/user/_search?q=age[18 TO 23]&sort=age:desc&from=0&size=2
### 查詢區間 年齡18-29之間的 降序排列 、顯示5條數據、 只顯示 name、age字段
GET /myindex/user/_search?q=age[18 TO 29]&sort=age:desc&from=0&size=5&_source=name,age
Dsl語言查詢與過濾
什么是DSL語言
es中的查詢請求有兩種方式,一種是簡易版的查詢,另外一種是使用JSON完整的請求體,叫做結構化查詢(DSL)。
由於DSL查詢更為直觀也更為簡易,所以大都使用這種方式。
DSL查詢是POST過去一個json,由於post的請求是json格式的,所以存在很多靈活性,也有很多形式。
##term是代表完全匹配,即不進行分詞器分析,文檔中必須包含整個搜索的詞匯。
#### term 精准查詢 相當於 equals
GET /myindex/user/_search
{
"query":{
"term":{
"name":"xiaoming"
}
}
}
####match查詢相當於模糊匹配,只包含其中一部分關鍵詞就行.
#### match 精准查詢 相當於 like,只對中文有效
GET /myindex/user/_search
{
"from":0,
"size":2,
"query":{
"match":{
"sex":"男"
}
}
}
使用filter過濾年齡
###### 使用filter 過濾 match_all 查詢所有、flter range 表示 age大於17 小於24 、_source 表示顯示的字段
GET /myindex/user/_search
{
"query":{
"bool":{
"must":[
{
"match_all":{
}
}
],
"filter":{
"range":{
"age":{
"gt":17,
"lte":24
}
}
}
}
},
"from":0,
"size":10,
"_source":[
"name",
"age"
]
}
Term與Match區別
Term查詢不會對字段進行分詞查詢,會采用精確匹配。
Match會根據該字段的分詞器,進行分詞查詢。
分詞器
什么是分詞器
因為Elasticsearch中默認的標准分詞器分詞器對中文分詞不是很友好,會將中文詞語拆分成一個一個中文的漢子。因此引入中文分詞器-es-ik插件 。
standard分詞器:
http://192.168.0.110:9200/_analyze
參數:
{
"analyzer":"standard",
"text":"小明"
}
結果為:
{
"tokens":[
{
"token":"小",
"start_offset":0,
"end_offset":1,
"type":"<IDEOGRAPHIC>",
"position":0
},
{
"token":"明",
"start_offset":1,
"end_offset":2,
"type":"<IDEOGRAPHIC>",
"position":1
}
]
}
由上面的結果可以看出來,這個分詞器 "analyzer":"standard" 會把結果都拆分成一個個的中文漢字,這肯定是不對的,所以我們需要使用 ik 分詞器。
ik 官方網站下載 https://github.com/medcl/elasticsearch-analysis-ik/releases
注意: es-ik分詞插件版本一定要和es安裝的版本對應
第一步:下載es的IK插件 ,可重命名文件名稱。
第二步: 上傳到/usr/local/elasticsearch-6.4.3/plugins
第三步: 重啟elasticsearch即可
ik_smart 分詞器:
http://192.168.0.110:9200/_analyze
參數:
{
"analyzer":"ik_smart",
"text":"小明"
}
結果為:
{
"tokens":[
{
"token":"小明",
"start_offset":0,
"end_offset":2,
"type":"CN_WORD",
"position":0
}
]
}
由上面結果可以看出 使用 ik 分詞器 "analyzer":"ik_smart" 會把結果正確顯示出來。
自定義擴展詞
進入到 es 的安裝目錄下,找到 ik 插件目錄。
cd /usr/local/es/elasticsearch-6.4.3/plugins/ik/config
在這個目錄新建一個自定義擴展詞放到一個新建文件中。
mkdir custom
vi vi new_word.dic
自定義分詞器創建好之后,還需要在 ik 配置文件中 指定該分詞器文件。
修改 ik 配置文件 ,指定自己新建的分詞器文件。
cd /usr/local/es/elasticsearch-6.4.3/plugins/ik/config
vi IKAnalyzer.cfg.xml
配置好之后,啟動 es,如果看到如下圖所示的 新建 的分詞文件被加載,說明成功了,直接使用 postman 發送請求來驗證。
postman 請求地址:http://192.168.0.110:9200/_analyze
參數:
{
"analyzer":"ik_smart",
"text":"小愛同學"
}
響應結果:
{
"tokens":[
{
"token":"小愛同學",
"start_offset":0,
"end_offset":4,
"type":"CN_WORD",
"position":0
}
]
}
如上圖所示,則表示我們配置的自定義分詞器成功了。
文檔映射
已經把ElasticSearch的核心概念和關系數據庫做了一個對比,索引(index)相當於數據庫,類型(type)相當於數據表,映射(Mapping)相當於數據表的表結構。ElasticSearch中的映射(Mapping)用來定義一個文檔,可以定義所包含的字段以及字段的類型、分詞器及屬性等等。
文檔映射就是給文檔中的字段指定字段類型、分詞器。
映射的分類
動態映射
我們知道,在關系數據庫中,需要事先創建數據庫,然后在該數據庫實例下創建數據表,然后才能在該數據表中插入數據。而ElasticSearch中不需要事先定義映射(Mapping),文檔寫入ElasticSearch時,會根據文檔字段自動識別類型,這種機制稱之為動態映射。默認映射為 long 類型。
靜態映射
在ElasticSearch中也可以事先定義好映射,包含文檔的各個字段及其類型等,這種方式稱之為靜態映射。
String 類型分為text、keyword。
text:會進行分詞查詢。
keywork:不會進行分詞查詢。
ES類型支持
基本類型
符串:string,string類型包含 text 和 keyword。
text:該類型被用來索引長文本,在創建索引前會將這些文本進行分詞,轉化為詞的組合,建立索引;允許es來檢索這些詞,text類型不能用來排序和聚合。
keyword:該類型不需要進行分詞,可以被用來檢索過濾、排序和聚合,keyword類型自讀那只能用本身來進行檢索(不可用text分詞后的模糊檢索)。
注意: keyword類型不能分詞,Text類型可以分詞查詢
數指型:long、integer、short、byte、double、float
日期型:date
布爾型:boolean
二進制型:binary
數組類型(Array datatype)
復雜類型
地理位置類型(Geo datatypes)
地理坐標類型(Geo-point datatype):geo_point 用於經緯度坐標
地理形狀類型(Geo-Shape datatype):geo_shape 用於類似於多邊形的復雜形狀
特定類型(Specialised datatypes)
Pv4 類型(IPv4 datatype):ip 用於IPv4 地址
Completion 類型(Completion datatype):completion 提供自動補全建議
Token count 類型(Token count datatype):token_count 用於統計做子標記的字段的index數目,該值會一直增加,不會因為過濾條件而減少
mapper-murmur3 類型:通過插件,可以通過_murmur3_來計算index的哈希值
附加類型(Attachment datatype):采用mapper-attachments插件,可支持_attachments_索引,例如 Microsoft office 格式,Open Documnet 格式, ePub,HTML等
創建文檔類型並且指定類型
##### 創建文檔類型並且指定類型
POST /myindex/_mapping/user
{
"user":{
"properties":{
"age":{
"type":"integer"
},
"sex":{
"type":"text"
},
"name":{
"type":"text",
"analyzer":"ik_smart"
}
}
}
}
如果創建失敗,需要先刪除之前的索引,在重新新建即可。
未指定類型之前:
##### 查看映射類型
GET /myindex/user/_mapping
{
"myindex":{
"mappings":{
"user":{
"properties":{
"age":{
"type":"long"
},
"id":{
"type":"text",
"fields":{
"keyword":{
"type":"keyword",
"ignore_above":256
}
}
},
"name":{
"type":"text",
"fields":{
"keyword":{
"type":"keyword",
"ignore_above":256
}
}
},
"sex":{
"type":"text",
"fields":{
"keyword":{
"type":"keyword",
"ignore_above":256
}
}
}
}
}
}
}
}
指定類型之后:
##### 查看映射類型
GET /myindex/user/_mapping
{
"myindex":{
"mappings":{
"user":{
"properties":{
"age":{
"type":"integer"
},
"name":{
"type":"text",
"analyzer":"ik_smart"
},
"sex":{
"type":"text"
}
}
}
}
}
}
es 官網: https://www.elastic.co/cn/products/elasticsearch
es 使用文檔:https://es.xiaoleilu.com/
es 下載地址:https://www.elastic.co/cn/downloads/elasticsearch
百度百科:https://baike.baidu.com/item/elasticsearch/3411206?fr=aladdin
什么是PB級別:https://baike.baidu.com/item/%E6%8B%8D%E5%AD%97%E8%8A%82/1453828?fromtitle=PetaByte&fromid=5910820