1. ES操作方法
1、在可視化界面Kibana上執行代碼:
GET _search
{
"query": {
"match_all": {}
}
}
PUT /mytest/user/1
{
"name": "xj",
"age": 21,
"sex": 0,
"car": "奧迪a6l"
}
GET /mytest/user/1
2、使用RESTful創建文檔
路徑:/索引/類型/id
GET命令-查詢:
方法:get
地址:http://192.168.170.128:9200/mytest/user/1
結果:
{
"_index": "mytest",
"_type": "user",
"_id": "1",
"_version": 2,
"found": true,
"_source": {
"name": "xj",
"age": 21,
"sex": 0,
"car": "奧迪a6l"
}
}
說明:實際上Kibana也是通過restful請求的,其中url在配置文件中配置了。
2. Elasticsearch倒排索引原理
全文檢索底層采用倒排索引。
倒排索引比數據庫中的B-tree樹查詢效率快。
分析倒排索引:
正排索引是從文檔到關鍵字的映射(已知文檔求關鍵字),倒排索引是從關鍵字到文檔的映射(已知關鍵字求文檔)。
文檔內容:
序號 |
文檔內容 |
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 |
說明:
單詞ID:唯一標識
單詞:出現次數較多的單詞,提取出來,存儲在一個詞庫中。
倒排列表:存儲包含對應單詞的文檔的id
3. Elasticsearch高級查詢(重點)
3.1 數據插入:POST、PUT
# POST 插入數據,可以不加id
POST /mytest/user/
{
"name": "xj_2",
"age": 21,
"sex": 0,
"car": "奧迪a6l"
}
# 結果:
{
"_index": "mytest",
"_type": "user",
"_id": "cycedXwBx9h5nuD8Z6Xh",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 2,
"_primary_term": 2
}
說明:POST生成的id是ES自動生成的不重復標志
# PUT 插入數據,必須加id
PUT /mytest/user/1
{
"name": "xj",
"age": 21,
"sex": 0,
"car": "奧迪a6l"
}
# 結果:
{
"_index": "mytest",
"_type": "user",
"_id": "1",
"_version": 3,
"result": "updated",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 2,
"_primary_term": 2
}
3.2 數據查詢:GET
### 簡單查詢
# 根據id進行查詢
GET /mytest/user/1
# 查當前索引下所有數據
GET /mytest/user/_search
# 查當前索引下多個id的數據
GET /mytest/user/_mget
{
"ids": ["1","2"]
}
### 復雜查詢
# 查詢年齡age為21
GET /mytest/user/_search?q=age:21
# 查詢年齡age為30歲到60歲之間
GET /mytest/user/_search?q=age[30 TO 60]&sort=age:desc
# 查詢年齡age為30歲到60歲之間&倒序排列
GET /mytest/user/_search?q=age[20 TO 60]&sort=age:desc
# 查詢年齡age為30歲到60歲之間&倒序排列&分頁顯示前2條
GET /mytest/user/_search?sort=age:desc&size=2
# 查詢年齡age為30歲到60歲之間&倒序排列&分頁顯示:從第3條開始查2條
GET /mytest/user/_search?sort=age:desc&from=2&size=2
3.3 DSL語言查詢與過濾
3.3.1 什么是DSL語言
1、ES中的查詢請求有兩種方式:
(1)簡易版的查詢
(2)使用JSON完整的請求體,叫做結構化查詢(DSL)
2、由於DSL查詢更為直觀也更為簡易,所以大都使用這種方式。
3、DSL查詢是POST過去一個JSON,由於POST的請求是JSON格式的,所以存在很多靈活性,也有很多形式。
3.3.2 具體查詢示例
1、term查詢:精確匹配,不會做分詞匹配
GET mytest/user/_search
{
"query": {
"term": {
"name": "xy"
}
}
}
2、match查詢:模糊查詢,支持分詞查詢,對match對象里邊的字段分詞查詢
說明:下邊示例是對car字段分詞查詢,可以查單個漢字,但不可以查單個字母
GET mytest/user/_search
{
"query": {
"match": {
"car": "奧迪"
}
}
}
GET mytest/user/_search
{
"query": {
"match": {
"car": "奧迪a4l"
}
}
}
GET mytest/user/_search
{
"query": {
"match": {
"car": "a4l"
}
}
}
3、分頁:from起始位置,size記錄條數
說明:from=0為第一條數據
GET mytest/user/_search
{
"from": 0,
"size": 2,
"query": {
"match": {
"car": "奧迪"
}
}
}
4、使用filter過濾年齡
說明:
(1)過濾年齡大於等於21歲小於等於50歲
(2)_source字段用於設置查詢結果顯示那幾個字段
GET /mytest/user/_search
{
"query": {
"bool": {
"must": [
{
"match_all": {}
}
],
"filter": {
"range": {
"age": {
"gte": 21,
"lte": 50
}
}
}
}
},
"from": 0,
"size": 3,
"_source": ["name", "age"]
}
# 結果
{
"took": 17,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 6,
"max_score": 1,
"hits": [
{
"_index": "mytest",
"_type": "user",
"_id": "5",
"_score": 1,
"_source": {
"name": "xm",
"age": 48
}
},
{
"_index": "mytest",
"_type": "user",
"_id": "cycedXwBx9h5nuD8Z6Xh",
"_score": 1,
"_source": {
"name": "xj_2",
"age": 21
}
},
{
"_index": "mytest",
"_type": "user",
"_id": "2",
"_score": 1,
"_source": {
"name": "xh",
"age": 21
}
}
]
}
}
4. ElasticsearchIK分詞器原理(重點)
4.1 傳統分詞器原理
默認分詞器:文字按單個字為一個單詞,英文可以以一個單詞為單詞
http://192.168.170.128:9200/_analyze
{
"analyzer": "standard",
"text": "奧迪a4l"
}
# 結果
{
"tokens": [
{
"token": "奧",
"start_offset": 0,
"end_offset": 1,
"type": "<IDEOGRAPHIC>",
"position": 0
},
{
"token": "迪",
"start_offset": 1,
"end_offset": 2,
"type": "<IDEOGRAPHIC>",
"position": 1
},
{
"token": "a4l",
"start_offset": 2,
"end_offset": 5,
"type": "<ALPHANUM>",
"position": 2
}
]
}
5. ElasticsearchIK中文分詞器
5.1 為什么中文分詞器
因為Elasticsearch中默認的標准分詞器對中文分詞不是很友好,會將中文詞語拆分成一個一個中文的漢字作為單詞。因此引入中文分詞器elasticsearch-analysis-ik插件
5.2 中文分詞器下載安裝
5.2.1 下載地址
https://github.com/medcl/elasticsearch-analysis-ik/releases
注意:es-ik分詞插件的版本一定要和es安裝的版本對應。
5.2.2 安裝步驟
(1)將下載es的IK插件,解壓並重命名為ik
(2)上傳到/usr/local/elasticsearch-6.4.3/plugins/
(3)重啟elasticsearch
檢查安裝結果:
6. IK自定義中文詞典熱詞
步驟:
1、打開ik配置文件目錄:cd /usr/local/elasticsearch-6.4.3/plugins/ik/config/
2、新建文件:touch custom/new_word.dic
3、添加分詞:vi custom/new_word.dic
王者榮耀
一帶一路
4、修改配置文件:vi IKAnalyzer.cfg.xml
5、重啟elasticsearch
在重啟日志中可以看到加載了new_word.dic
6、測試
7. Elasticsearch Mapping映射
7.1 文檔映射的概念
已經把ElasticSearch的核心概念和關系數據庫做了一個對比,索引(index)相當於數據庫,類型(type)相當於數據表,映射(Mapping)相當於數據表的表結構。ElasticSearch中的映射(Mapping)用來定義一個文檔,可以定義所包含的字段以及字段的類型、分詞器及屬性等等。
文檔映射就是給文檔中的字段指定字段類型、分詞器。
使用GET /mymayikt/user/_mapping
7.2 映射的分類
7.2.1 動態映射
我們知道,在關系數據庫中,需要事先創建數據庫,然后在該數據庫實例下創建數據表,然后才能在該數據表中插入數據。而ElasticSearch中不需要事先定義映射(Mapping),文檔寫入ElasticSearch時,會根據文檔字段自動識別類型,這種機制稱之為動態映射。
7.2.1 靜態映射
在ElasticSearch中也可以事先定義好映射,包含文檔的各個字段及其類型等,這種方式稱之為靜態映射。
自動映射類型:
PUT /mytest/user/1
{
"name": "xj",
"age": 21,
"sex": 0,
"car": "奧迪a6l"
}
文檔映射:
命令:
# 文檔映射
POST /mytest/_mapping/user
{
"user": {
"properties": {
"age": {
"type": "integer"
},
"sex": {
"type": "integer"
},
"name": {
"type": "text",
"analyzer": "ik_smart",
"search_analyzer": "ik_smart"
},
"car": {
"type": "keyword"
}
}
}
}
報錯:不能給已經創建好並且有內容的索引添加映射類型。
新建一個索引,再設置映射:
# 創建文檔
PUT /mytest_1
# 文檔映射
POST /mytest_1/_mapping/user
{
"user": {
"properties": {
"age": {
"type": "integer"
},
"sex": {
"type": "integer"
},
"name": {
"type": "text",
"analyzer": "ik_smart",
"search_analyzer": "ik_smart"
},
"car": {
"type": "keyword"
}
}
}
}
# 插入數據
PUT /mytest_1/user/1
{
"name": "xj",
"age": 21,
"sex": 0,
"car": "奧迪a6l"
}
PUT /mytest_1/user/2
{
"name": "xh",
"age": 21,
"sex": 1,
"car": "保時捷911"
}
# 通過模糊查詢查“奧迪”,查不到,因為car類型為keyword
GET /mytest_1/user/_search
{
"query": {
"match": {
"car": "奧迪"
}
}
}
# 修改文檔映射類型(不可以直接修改,先刪除索引再重新創建)
DELETE /mytest_1
PUT /mytest_1
POST /mytest_1/_mapping/user
{
"user": {
"properties": {
"age": {
"type": "integer"
},
"sex": {
"type": "integer"
},
"name": {
"type": "text",
"analyzer": "ik_smart",
"search_analyzer": "ik_smart"
},
"car": {
"type": "text",
"analyzer": "ik_smart"
}
}
}
}
# 插入數據
PUT /mytest_1/user/1
{
"name": "xj",
"age": 21,
"sex": 0,
"car": "奧迪a6l"
}
PUT /mytest_1/user/2
{
"name": "xh",
"age": 21,
"sex": 1,
"car": "保時捷911"
}
PUT /mytest_1/user/3
{
"name": "xx",
"age": 23,
"sex": 0,
"car": "奧迪a4l"
}
# 再次通過模糊查詢查“奧迪”,能查到2條,因為car類型改為了text
GET /mytest_1/user/_search
{
"query": {
"match": {
"car": "奧迪"
}
}
}
7.3 ES支持的數據類型
7.3.1 基本類型
字符串:string,string類型包含 text 和 keyword。
text:該類型被用來索引長文本,在創建索引前會將這些文本進行分詞,轉化為詞的組合,建立索引;允許es來檢索這些詞,text類型不能用來排序和聚合。
keyword:該類型不需要進行分詞,可以被用來檢索過濾、排序和聚合,keyword類型自讀那只能用本身來進行檢索(不可用text分詞后的模糊檢索)。
注意: keyword類型不能分詞,Text類型可以分詞查詢
數值型:long、integer、short、byte、double、float
日期型:date
布爾型:boolean
二進制型:binary
數組類型(Array datatype)
7.3.2 復雜類型
地理位置類型(Geo datatypes)
地理坐標類型(Geo-point datatype):geo_point 用於經緯度坐標
地理形狀類型(Geo-Shape datatype):geo_shape 用於類似於多邊形的復雜形狀
7.3.3 特定類型(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等
Analyzer 索引分詞器,索引創建的時候使用的分詞器 比如ik_smart
Search_analyzer 搜索字段的值時,指定的分詞器