目錄
- 簡介
- 安裝
環(huán)境信息
2.1 安裝 JDK
2.2 修改系統(tǒng)設(shè)置
2.3 創(chuàng)建用戶
2.4 安裝 Elastic Search
2.5 安裝 Kibana
2.6 配置中文分詞器 analysis ik - 概念
3.1 基本概念
3.3.1 Index
3.3.2 Document
3.3.3 Type
3.3.4 Mapping
3.2 分詞
3.3 倒排索引 - 在 Kibana 中進行增刪改查
4.1 創(chuàng)建索引
4.2 新增
4.3 查詢
4.4 更新
4.5 刪除
4.6 MultiGet 批量獲取
4.7 Bulk 批量添加、修改天梧、刪除 - 版本控制
5.1 內(nèi)部版本控制
5.2 外部版本控制 - Mapping
6.1 什么是 Mapping
6.2 Mapping 的數(shù)據(jù)類型
6.3 Mapping 的屬性 - 基本查詢(英文)
7.1 簡單查詢
7.2 term 查詢和 terms 查詢
7.3 控制查詢返回的數(shù)量
7.4 返回版本號
7.5 match 查詢
7.6 指定返回的字段
7.7 控制加載的字段
7.8 排序
7.9 前綴匹配查詢
7.10 范圍查詢
7.11 wildcard查詢
7.12 fuzzy 模糊查詢
7.13 高亮搜索結(jié)果 - 基本查詢(中文)
- 過濾查詢(Filter )
9.1 簡單過濾查詢
9.2 bool 過濾查詢
9.3 范圍過濾
9.4 非空過濾
9.5 過濾器緩存 - 聚合查詢
- 復(fù)合查詢
11.1 bool 查詢
11.2 constant_score 查詢
1. 簡介
Elastic Stack
Elastic Stack 是 Elastic 公司一系列軟件的集合倦春,是一個開源的解決方案泽疆,可以收集各種類型歼培,各種格式的源數(shù)據(jù)靡狞,同時提供數(shù)據(jù)搜索我衬,分析和可視化的展示鲤遥。
-
Elasticsearch:是一個基于 Lucene 的擁有分布式多用戶能力的全文搜索引擎,它提供了 RESTful 接口硅卢。了解 RESTful API
Kibana:配合 Elasticsearch 使用的可視化工具射窒。
Beats:一個精簡的數(shù)據(jù)采集器。
Logstash:用于數(shù)據(jù)的抽取和過濾将塑,類似 ETL。
2. 安裝
環(huán)境信息
系統(tǒng):Centos 7.6
機器IP:192.168.0.233
JDK:1.8.0_211
要安裝的軟件
Elastic Search:7.2.0
Kinaba:7.2.0
2.1 安裝 JDK
查看安裝方法
要求 1.8 及以上
2.2 修改系統(tǒng)設(shè)置
使用 root 用戶登錄
修改最大線程數(shù)和句柄數(shù)蝌麸,vi /etc/security/limits.conf
添加以下內(nèi)容
* soft nofile 65536
* hard nofile 65536
* soft nproc 4096
* hard nproc 4096
用戶退出后重新登陸生效
修改虛擬內(nèi)存大小点寥,vi /etc/sysctl.conf
添加以下內(nèi)容
vm.max_map_count=262144
使設(shè)置生效 sysctl -p
2.3 創(chuàng)建用戶
ES 默認不能使用 root 用戶啟動,如果用 root 用戶啟動来吩,啟動時需要加上參數(shù) -Des.insecure.allow.root=true
這里就先創(chuàng)建一個新用戶吧
創(chuàng)建用戶: useradd es
設(shè)置密碼: passwd es
切換到新用戶: su es
2.4 安裝 Elastic Search
解壓: tar -zxvf elasticsearch-7.2.0-linux-x86_64.tar.gz
修改文件夾名稱: mv elasticsearch-7.2.0 elasticsearch
修改配置文件: vi elasticsearch/config/elasticsearch.yml
-- 修改地址:network.host: 192.168.0.233
-- 節(jié)點名稱: node.name: node-1
-- 集群設(shè)置:cluster.initial_master_nodes: ["node-1"]
運行: ./elasticsearch/bin/elasticsearch &
瀏覽器訪問 http://192.168.0.233:9200
會得到一些信息:
{
"name": "node-1",
"cluster_name": "elasticsearch",
"cluster_uuid": "kMaKec3GQ6SZt9OpMwvRJg",
"version": {
"number": "7.2.0",
"build_flavor": "default",
"build_type": "tar",
"build_hash": "508c38a",
"build_date": "2019-06-20T15:54:18.811730Z",
"build_snapshot": false,
"lucene_version": "8.0.0",
"minimum_wire_compatibility_version": "6.8.0",
"minimum_index_compatibility_version": "6.0.0-beta1"
},
"tagline": "You Know, for Search"
}
2.5 安裝 Kibana
解壓: tar -zxvf kibana-7.2.0-linux-x86_64.tar.gz
修改文件夾名稱: mv kibana-7.2.0-linux-x86_64 kibana
修改配置文件: vi kibana/config/kibana.yml
-- 修改 ES 地址: elasticsearch.hosts: ["http://192.168.0.233:9200"]
-- 修改 kibana 地址:server.host: "192.168.0.233"
-- 修改語言: i18n.locale: "zh-CN"
運行: ./kibana/bin/kibana &
瀏覽器訪問 http://192.168.0.233:5601
敢辩,中文界面感覺很親切
2.6 配置中文分詞器 IK
此章節(jié)不是必須,若不需要可跳過
前往下載插件 選擇對應(yīng)的 7.2.0 版本
將插件放到 elasticsearch/plugins/ik
目錄
[es@localhost plugins]$ pwd
/home/es/elasticsearch/plugins/ik
[es@localhost plugins]$ ls
elasticsearch-analysis-ik-7.2.0.zip
解壓 unzip elasticsearch-analysis-ik-7.2.0.zip
弟疆,系統(tǒng)沒有 unzip
命令可 查看安裝方法
重啟 ES 可以看到下面的信息就表示插件安裝成功了
[2019-07-20T19:25:29,310][INFO ][o.e.p.PluginsService ] [node-1] loaded plugin [analysis-ik]
現(xiàn)在可以將插件壓縮包刪除了 rm elasticsearch-analysis-ik-7.2.0.zip
3. 概念
3.1 基本概念
3.3.1 Index
Elastic 會索引所有字段戚长,經(jīng)過處理后寫入一個倒排索引(Inverted Index)。查找數(shù)據(jù)的時候怠苔,直接查找該索引同廉。
所以,Elastic 數(shù)據(jù)管理的頂層單位就叫做 Index(索引)。它是單個數(shù)據(jù)庫的同義詞迫肖。每個 Index (即數(shù)據(jù)庫)的名字必須是小寫锅劝。
類似于關(guān)系型數(shù)據(jù)庫中的 Database。
3.3.2 Document
Index 里面單條的記錄稱為 Document(文檔)蟆湖。許多條 Document 構(gòu)成了一個 Index故爵。
Document 使用 JSON 格式表示,同一個 Index 里面的 Document隅津,不要求有相同的結(jié)構(gòu)(scheme)诬垂,但是最好保持相同,這樣有利于提高搜索效率伦仍。
類似于關(guān)系型數(shù)據(jù)庫中的數(shù)據(jù)剥纷,一個 Document 相當(dāng)于一行數(shù)據(jù)。
3.3.3 Type
Document 可以分組呢铆,比如weather
這個 Index 里面晦鞋,可以按城市分組(北京和上海),也可以按氣候分組(晴天和雨天)棺克。這種分組就叫做 Type悠垛,它是虛擬的邏輯分組,用來過濾 Document娜谊。
不同的 Type 應(yīng)該有相似的結(jié)構(gòu)(schema)确买,舉例來說,id
字段不能在這個組是字符串纱皆,在另一個組是數(shù)值湾趾。這是與關(guān)系型數(shù)據(jù)庫的表的一個區(qū)別伐坏。
性質(zhì)完全不同的數(shù)據(jù)(比如products
和logs
)應(yīng)該存成兩個 Index蒂培,而不是一個 Index 里面的兩個 Type。
類似于關(guān)系型數(shù)據(jù)庫中的 Table目溉。
注意:6.x 以前版本一個 Index 可以有多個 Type近迁;6.x 版本艺普,一個 Index 只能有一個 Type;7.x 版本拋棄 了 Type 這個概念)鉴竭。
和關(guān)系型數(shù)據(jù)庫做個類比的話歧譬,他們的關(guān)系是:
Index > Database
Document > data
Type > Table
可以想象一下,有一個數(shù)據(jù)庫搏存,它的一個數(shù)據(jù)庫實例(Index)只能有一張表(Type)瑰步,我們直接往這個實例中插入數(shù)據(jù)(Document)。
3.3.4 Mapping
參考第6節(jié):Mapping 和數(shù)據(jù)類型
3.2 分詞
分詞:從一串文本中切分出一個一個的詞條璧眠,并對每個詞條進行標準化
分詞器包括三部分:
character filter:分詞之前的預(yù)處理缩焦,過濾掉HTML標簽读虏,特殊符號轉(zhuǎn)換等
tokenizer:分詞
token filter:標準化
內(nèi)置分詞器:
- standard 分詞器:
Elasticsearch 默認的分詞器,它會將詞匯單元轉(zhuǎn)換成小寫形式舌界,并去除停用詞和標點符號掘譬,支持中文采用的方法為單字切分 - simple 分詞器:
首先會通過非字母字符來分割文本信息,然后將詞匯單元統(tǒng)一為小寫形式呻拌。該分析器會去掉數(shù)字類型的字符葱轩。 - Whitespace 分詞器:
僅僅是去除空格,對字符沒有l(wèi)owcase化,不支持中文藐握;并且不對生成的詞匯單元進行其他的標準化處理靴拱。 - language 分詞器:
特定語言的分詞器,不支持中文
3.3 倒排索引
Elasticsearch 使用一種稱為倒排索引的結(jié)構(gòu)猾普,它適用于快速的全文搜索袜炕。一個倒排索引由文檔中所有不重復(fù)詞的列表構(gòu)成,對于其中每個詞初家,有一個包含它的文檔列表偎窘。
示例1:
-
假設(shè)文檔集合包含五個文檔,每個文檔內(nèi)容如圖所示溜在,在圖中最左端一欄是每個文檔對應(yīng)的文檔編號陌知。
-
中文和英文等語言不同,單詞之間沒有明確分隔符號掖肋,所以首先要用分詞系統(tǒng)將文檔自動切分成單詞序列仆葡。這樣每個文檔就轉(zhuǎn)換為由單詞序列構(gòu)成的數(shù)據(jù)流,為了系統(tǒng)后續(xù)處理方便志笼,需要對每個不同的單詞賦予唯一的單詞編號沿盅,同時記錄下哪些文檔包含這個單詞,在如此處理結(jié)束后纫溃,我們可以得到最簡單的倒排索引
-
索引系統(tǒng)還可以記錄除此之外的更多信息,下圖還記載了單詞頻率信息(TF)即這個單詞在某個文檔中的出現(xiàn)次數(shù)腰涧,之所以要記錄這個信息,是因為詞頻信息在搜索結(jié)果排序時皇耗,計算查詢和文檔相似度是很重要的一個計算因子南窗,所以將其記錄在倒排列表中,以方便后續(xù)排序時進行分值計算郎楼。
倒排列表中還可以記錄單詞在某個文檔出現(xiàn)的位置信息
(1,<11>,1),(2,<7>,1),(3,<3,9>,2)
上面表示:
在 id 為1的文檔中出現(xiàn)1次,位置為11
在 id 為2的文檔中出現(xiàn)1次窒悔,位置為7
在 id 為3的文檔中出現(xiàn)2次呜袁,位置為3和9
示例2:
現(xiàn)在有兩個文檔
1.The quick brown fox jumped over the lazy dog
2.Quick brown foxes leap over lazy dogs in summer
我們來手動進行分詞:
Term | Doc_1 | Doc_2 |
---|---|---|
Quick | X | |
The | X | |
brown | X | X |
dog | X | |
dogs | X | |
fox | X | |
foxes | X | |
in | X | |
jumped | X | |
lazy | X | X |
leap | X | |
over | X | X |
quick | X | |
summer | X | |
the | X |
這里搜索 quick brown 的話,就會是下面這個情況:
Term | Doc_1 | Doc_2 |
---|---|---|
brown | X | X |
quick | X | |
Total | 2 | 1 |
可以看到文檔1中兩個單詞都有简珠,文檔2中只有一個阶界,說明文檔1的匹配度比文檔2要高虹钮。
但是這樣分詞有很多問題:
- Quick 和 quick 以獨立的詞條出現(xiàn),然而用戶可能認為它們是相同的詞膘融。
- fox 和 foxes 非常相似, 就像 dog 和 dogs 芙粱;他們有相同的詞根。
- jumped 和 leap, 盡管沒有相同的詞根氧映,但他們的意思很相近春畔。他們是同義詞。
- 搜索含有 Quick fox的文檔是搜索不到的
實際上岛都,ES 在建立倒排索引時律姨,會使用標準化規(guī)則(normalization):
建立倒排索引的時候,會對拆分出的各個單詞進行相應(yīng)的處理臼疫,以提升后面搜索的時候能夠搜索到相關(guān)聯(lián)的文檔的概率
實際上的倒排索引:
Term | Doc_1 | Doc_2 |
---|---|---|
brown | X | X |
dog | X | X |
fox | X | X |
in | X | |
jump | X | X |
lazy | X | X |
over | X | X |
quick | X | X |
summer | X | |
the | X | X |
4. 在 Kibana 中進行增刪改查
進入 Kibana 中的開發(fā)工具
4.1 創(chuàng)建索引
PUT /lib/
{
"settings": {
"index": {
"number_of_shards": 3,
"number_of_replicas": 0
}
}
}
number_of_shards
分片數(shù)量择份,一旦確定是不能修改的
number_of_replicas
備份數(shù)量,因為只有一臺機器烫堤,就設(shè)置為0
點擊綠色箭頭運行
顯示結(jié)果
{
"acknowledged" : true,
"shards_acknowledged" : true,
"index" : "lib"
}
創(chuàng)建索引時可以不給定參數(shù)荣赶,此時使用默認配置
PUT lib2
查看 lib2 的索引配置
GET lib2/_settings
{
"lib2" : {
"settings" : {
"index" : {
"creation_date" : "1563624230345",
"number_of_shards" : "1",
"number_of_replicas" : "1",
"uuid" : "PhbovgGYTHyc8UlF04nqPg",
"version" : {
"created" : "7020099"
},
"provided_name" : "lib2"
}
}
}
}
查看所有索引的配置
GET _all/_settings
4.2 新增
新增一個用戶信息(user)的文檔
指定 id PUT /Index/Type/id
(覆蓋) 或 不指定 id POST /Index/Type/
在 6.x 及以前的版本中,可以自己定義 Type鸽斟,比如 PUT /lib/user/1
拔创,7.x 版本只能使用 _doc
或 _create
作為 Type
指定 id:
PUT /lib/_doc/1
{
"first_name": "Jane",
"last_name": "Smith",
"age": 32,
"about": "I like to collect rock albums",
"interests": [
"music"
]
}
{
"_index" : "lib",
"_type" : "_doc",
"_id" : "1",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 1,
"_primary_term" : 1
}
不指定 id 會由 es 自動生成 id:
POST /lib/_doc/
{
"first_name": "Jane",
"last_name": "Smith",
"age": 32,
"about": "I like to collect rock albums",
"interests": [
"music"
]
}
{
"_index" : "lib",
"_type" : "_doc",
"_id" : "QUVVD2wBaGnqhTuBKxcM",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 2,
"_primary_term" : 1
}
4.3 查詢
GET /Index/Index/id?_source=key1,key2···
查詢 id 為 1 的文檔
GET /lib/_doc/1
{
"_index" : "lib",
"_type" : "_doc",
"_id" : "1",
"_version" : 2,
"_seq_no" : 1,
"_primary_term" : 1,
"found" : true,
"_source" : {
"first_name" : "Jane",
"last_name" : "Smith",
"age" : 32,
"about" : "I like to collect rock albums",
"interests" : [
"music"
]
}
}
查詢 id 為 1 的文檔中的 age 和 about
GET /lib/_doc/1?_source=age,about
{
"_index" : "lib",
"_type" : "_doc",
"_id" : "1",
"_version" : 2,
"_seq_no" : 1,
"_primary_term" : 1,
"found" : true,
"_source" : {
"about" : "I like to collect rock albums",
"age" : 32
}
}
4.4 更新
更新有兩種:使用新的文檔將舊的覆蓋掉 或者 更新內(nèi)容 POST /Index/_update/id/
添加時 id 相同就會覆蓋,這里覆蓋把 age 改為 36
PUT /lib/_doc/1
{
"first_name": "Jane",
"last_name": "Smith",
"age": 36,
"about": "I like to collect rock albums",
"interests": [
"music"
]
}
或者使用 _update
只更新 age
POST /lib/_update/1/
{
"doc": {
"age": 33
}
}
4.5 刪除
刪除一個文檔 DELETE /Index/_doc/id
DELETE /lib/_doc/1
刪除 Index DELETE /Index
DELETE /lib
4.6 MultiGet 批量獲取
GET /_mget
如果索引相同湾盗,可以寫成 GET /Index/_mget
格式 :
GET /_mget
{
"docs": [
{
"_index": "Index", // 指定 index
"_id": id, // 指定 id
"_source": ["key1","key2"......] // 指定要獲取的字段
},
......
]
}
索引不同的示例:
GET /_mget
{
"docs": [
{
"_index": "lib",
"_id": 123,
"_source": ["age"]
},
{
"_index": "lib2",
"_id": 234,
"_source": ["first_name", "last_name"]
},
{
"_index": "lib3",
"_id": 345
}
]
}
索引相同的示例:
GET /lib/_mget
{
"docs": [
{
"_id": 1,
"_source": ["age"]
},
{
"_id": 2,
"_source": ["first_name", "last_name"]
},
{
"_id": 3
}
]
}
如果只有 id 參數(shù)伏蚊,可以寫成:
GET /lib/_mget
{
"ids": [
"1",
"2",
"3"
]
}
4.7 Bulk 批量添加、修改格粪、刪除
bulk 的格式:
POST /Index/_bulk
{action:{metadata}}
{requstBody}
......
action 有四種:
- create:文檔不存在時創(chuàng)建躏吊,如文檔已經(jīng)存在,則操作失敗
- update:更新文檔
- index:創(chuàng)建新文檔或替換已有文檔
- delete:刪除一個文檔
示例 1帐萎, 批量添加:
POST /lib/_bulk
{"index":{"_id":1}}
{"title":"Java","price":55}
{"index":{"_id":2}}
{"title":"Html5","price":45}
{"index":{"_id":3}}
{"title":"Php","price":35}
{"index":{"_id":4}}
{"title":"Python","price":50}
示例 2比伏, 多種操作同時執(zhí)行
POST /lib/_bulk
{"delete":{"_index":"lib2","_id":4}} // 刪除操作沒有請求體
{"create":{"_index":"tt","_id":"100"}}
{"name":"lisi"}
{"index":{"_index":"tt"}}
{"name":"zhaosi"}
{"update":{"_index":"lib2","_id":"4"}}
{"doc":{"price":58}}
bulk 會把要處理的數(shù)據(jù)載入內(nèi)存,所以數(shù)據(jù)量是有限制的疆导,最佳的數(shù)據(jù)量不是一個確定的數(shù)值赁项,它取決于你的硬件,你的文檔大小以及復(fù)雜性澈段,你的索引以及搜索的負載悠菜。
一般建議是1000-5000個文檔,大小建議是5-15MB败富,默認不能超過100M悔醋,可以在es的配置文件 elasticsearch.yml
中修改。
5. 版本控制
5.1 內(nèi)部版本控制
ElasticSearch 采用了樂觀鎖來保證數(shù)據(jù)的一致性兽叮,對文檔的每次操作都會使版本號 +1芬骄,ElasticSearch 的版本號的取值范圍為1到2^63-1猾愿。
當(dāng)用戶對 document 進行操作時,并不需要對該 document 作加鎖和解鎖的操作账阻,只需要指定要操作的版本即可蒂秘。當(dāng)版本號一致時,ElasticSearch 會允許該操作順利執(zhí)行淘太,而當(dāng)版本號存在沖突時姻僧,ElasticSearch 會提示沖突并拋出異常(VersionConflictEngineException)。
內(nèi)部版本控制使用的是 _version
查看一個文檔
GET /lib/_doc/1
可以看到文檔的版本號為 5
{
"_index" : "lib",
"_type" : "_doc",
"_id" : "1",
"_version" : 5,
"_seq_no" : 4,
"_primary_term" : 1,
"found" : true,
"_source" : {
"title" : "Java",
"price" : 58
}
}
當(dāng)更新的版本號錯誤時琴儿,會報錯:
PUT /lib/_doc/1?version=4
{
"first_name": "Jane1",
"last_name": "Smith1",
"age": 34,
"about": "I like to collect rock albums",
"interests": [
"music"
]
}
{
"error": {
"root_cause": [
{
"type": "action_request_validation_exception",
"reason": "Validation Failed: 1: internal versioning can not be used for optimistic concurrency control. Please use `if_seq_no` and `if_primary_term` instead;"
}
],
"type": "action_request_validation_exception",
"reason": "Validation Failed: 1: internal versioning can not be used for optimistic concurrency control. Please use `if_seq_no` and `if_primary_term` instead;"
},
"status": 400
}
5.2 外部版本控制
一般關(guān)系型數(shù)據(jù)庫使用時間戳來做版本控制段化,當(dāng) Elasticsearch 需要跟關(guān)系型數(shù)據(jù)庫同步時,就需要使用外部版本控制了造成。
Elasticsearch 在處理外部版本號時會與對內(nèi)部版本號的處理有些不同显熏。它不再是檢查 _version 是否與請求中指定的數(shù)值相同,而是檢查當(dāng)前的 _version 是否比指定的數(shù)值小晒屎。如果請求成功喘蟆,那么外部的版本號就會被存儲到文檔中的 _version中 。
外部版本控制使用 version_type=external
PUT /lib/_doc/1?version=11&version_type=external
{
"first_name": "Jane1",
"last_name": "Smith1",
"age": 34,
"about": "I like to collect rock albums",
"interests": [
"music"
]
}
{
"_index" : "lib",
"_type" : "_doc",
"_id" : "1",
"_version" : 88,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 5,
"_primary_term" : 1
}
6. Mapping
6.1 什么是 Mapping
當(dāng)創(chuàng)建 Index鼓鲁、Type蕴轨、Document 時,ES 會自動添加對應(yīng)的 Mapping骇吭,當(dāng) ES 在文檔中碰到一個以前沒見過的字段時橙弱,它會利用動態(tài)映射(dynamic mapping)來決定該字段的類型,并自動地對該字段添加映射燥狰。
可以通過 dynamic 設(shè)置來控制這一行為棘脐,它能夠接受以下的選項:
- true:默認值。動態(tài)添加字段
- false:忽略新字段
- strict:如果碰到陌生字段龙致,拋出異常
dynamic 設(shè)置可以適用在根對象上或者 object 類型的任意字段上蛀缝。
給 lib2 創(chuàng)建索引類型
POST /lib2
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 0
},
"mappings": {
"books": {
"properties": {
"title": {
"type": "text"
},
"name": {
"type": "text",
"index": false
},
"publish_date": {
"type": "date",
"index": false
},
"price": {
"type": "double"
},
"number": {
"type": "object",
"dynamic": true
}
}
}
}
}
使用 GET /Index/_mapping
查看 mapping
GET /lib/_mapping
{
"lib" : {
"mappings" : {
"properties" : {
"about" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"age" : {
"type" : "long"
},
"first_name" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
......
}
}
}
}
Mapping 定義了 type 中的每個字段的數(shù)據(jù)類型以及這些字段如何分詞等相關(guān)屬性。創(chuàng)建索引的時候,可以預(yù)先定義字段的類型以及相關(guān)屬性目代,這樣就能夠把日期字段處理成日期屈梁,把數(shù)字字段處理成數(shù)字,把字符串字段處理字符串值等榛了。
6.2 Mapping 的數(shù)據(jù)類型
核心數(shù)據(jù)類型(Core datatypes)
- 字符型:string在讶,string類型包括 text 和 keyword
text類型被用來索引長文本,在建立索引前會將這些文本進行分詞霜大,轉(zhuǎn)化為詞的組合真朗,建立索引。允許es來檢索這些詞語僧诚。text類型不能用來排序和聚合遮婶。
Keyword類型不需要進行分詞,可以被用來檢索過濾湖笨、排序和聚合旗扑。keyword 類型字段只能用本身來進行檢索 - 數(shù)字型:long, integer, short, byte, double, float
- 日期型:date
- 布爾型:boolean
- 二進制型:binary
復(fù)雜數(shù)據(jù)類型(Complex datatypes)
- 數(shù)組類型(Array datatype):數(shù)組類型不需要專門指定數(shù)組元素的type,例如:
字符型數(shù)組: [ "one", "two" ]
整型數(shù)組:[ 1, 2 ]
數(shù)組型數(shù)組:[ 1, [ 2, 3 ]] 等價于[ 1, 2, 3 ]
對象數(shù)組:[ { "name": "Mary", "age": 12 }, { "name": "John", "age": 10 }] - 對象類型(Object datatype):_ object _ 用于單個JSON對象慈省;
- 嵌套類型(Nested datatype):_ nested _ 用于JSON數(shù)組臀防;
地理位置類型(Geo datatypes)
- 地理坐標類型(Geo-point datatype):_ geo_point _ 用于經(jīng)緯度坐標;
- 地理形狀類型(Geo-Shape datatype):_ geo_shape _ 用于類似于多邊形的復(fù)雜形狀边败;
特定類型(Specialised datatypes)
- IPv4 類型(IPv4 datatype):_ ip _ 用于IPv4 地址袱衷;
- Completion 類型(Completion datatype):_ completion _提供自動補全建議;
- Token count 類型(Token count datatype):_ token_count _ 用于統(tǒng)計做了標記的字段的index數(shù)目笑窜,該值會一直增加致燥,不會因為過濾條件而減少。
- mapper-murmur3類型:通過插件排截,可以通過 _ murmur3 _ 來計算 index 的 hash 值嫌蚤;
- 附加類型(Attachment datatype):采用 mapper-attachments 插件,可支持_ attachments _ 索引断傲,例如 Microsoft Office 格式脱吱,Open Document 格式,ePub, HTML 等认罩。
6.3 Mapping 支持的屬性
- "store":false
是否單獨設(shè)置此字段的是否存儲而從_source字段中分離箱蝠,默認是false,只能搜索垦垂,不能獲取值 - "index": true
分詞宦搬,不分詞是:false,設(shè)置成false乔外,字段將不會被索引 - "analyzer":"ik"
指定分詞器,默認分詞器為standard analyzer - "boost":1.23
字段級別的分數(shù)加權(quán)床三,默認值是1.0 - "doc_values":false
對not_analyzed字段,默認都是開啟杨幼,分詞字段不能使用撇簿,對排序和聚合能提升較大性能,節(jié)約內(nèi)存 - fielddata":{"format":"disabled"}
針對分詞字段差购,參與排序或聚合時能提高性能四瘫,不分詞字段統(tǒng)一建議使用doc_value - "fields":{"raw":{"type":"string","index":"not_analyzed"}}
可以對一個字段提供多種索引模式,同一個字段的值欲逃,一個分詞找蜜,一個不分詞 - "ignore_above":100
超過100個字符的文本,將會被忽略稳析,不被索引 - "include_in_all":ture
設(shè)置是否此字段包含在_all字段中洗做,默認是true弓叛,除非index設(shè)置成no選項 - "index_options":"docs"
4個可選參數(shù)docs(索引文檔號) ,freqs(文檔號+詞頻),positions(文檔號+詞頻+位置诚纸,通常用來距離查詢)撰筷,offsets(文檔號+詞頻+位置+偏移量,通常被使用在高亮字段)分詞字段默認是position畦徘,其他的默認是docs - "norms":{"enable":true,"loading":"lazy"}
分詞字段默認配置毕籽,不分詞字段:默認{"enable":false},存儲長度因子和索引時boost井辆,建議對需要參與評分字段使用 关筒,會額外增加內(nèi)存消耗量 - "null_value":"NULL"
設(shè)置一些缺失字段的初始化值,只有string可以使用杯缺,分詞字段的null值也會被分詞 - "position_increament_gap":0
影響距離查詢或近似查詢蒸播,可以設(shè)置在多值字段的數(shù)據(jù)上火分詞字段上,查詢時可指定slop間隔夺谁,默認值是100 - "search_analyzer":"ik"
設(shè)置搜索時的分詞器廉赔,默認跟ananlyzer是一致的,比如index時用standard+ngram匾鸥,搜索時用standard用來完成自動提示功能 - "similarity":"BM25"
默認是TF/IDF算法蜡塌,指定一個字段評分策略,僅僅對字符串型和分詞類型有效 - "term_vector":"no"
默認不存儲向量信息勿负,支持參數(shù)yes(term存儲)馏艾,with_positions(term+位置),with_offsets(term+偏移量),with_positions_offsets(term+位置+偏移量) 對快速高亮fast vector highlighter能提升性能奴愉,但開啟又會加大索引體積琅摩,不適合大數(shù)據(jù)量用
7. 基本查詢(英文)
數(shù)據(jù)準備:
PUT /lib3
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 0
},
"mappings": {
"properties": {
"name": {
"type": "text"
},
"address": {
"type": "text"
},
"age": {
"type": "integer"
},
"interests": {
"type": "text"
},
"birthday": {
"type": "date"
}
}
}
}
PUT /lib3/_doc/1
{
"name": "lisi",
"address": "bei jing hai dian qu qing he zhen",
"age": 23,
"birthday": "1998-10-12",
"interests": "xi huan duanlian,hejiu,changge"
}
PUT /lib3/_doc/2
{
"name": "wangwu",
"address": "bei jing hai dian qu qing he zhen",
"age": 24,
"birthday": "1996-10-12",
"interests": "xi huan dalanqiu,paobu,changge"
}
PUT /lib3/_doc/3
{
"name": "zhaoliu",
"address": "bei jing hai dian qu qing he zhen",
"age": 26,
"birthday": "1999-10-12",
"interests": "xi huan shuijiao,chifan,fadai"
}
7.1 簡單查詢
查詢 name 為 lisi 的數(shù)據(jù)
GET /lib3/_search?q=name:lisi
{
"took" : 124, // 耗時
"timed_out" : false, // 是否超時
"_shards" : { //分片信息
"total" : 3, // 分片數(shù)量
"successful" : 3, // 3個分片都查詢成功了
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1, // 查詢出的文檔個數(shù)
"relation" : "eq"
},
"max_score" : 0.2876821, // 查出的文檔和執(zhí)行搜索的匹配度
"hits" : [
{
"_index" : "lib3",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.2876821,
"_source" : {
"name" : "lisi",
"address" : "bei jing hai dian qu qing he zhen",
"age" : 23,
"birthday" : "1998-10-12",
"interests" : "xi huan duanlian,hejiu,changge"
}
}
]
}
}
查詢有 changge 的興趣數(shù)據(jù),并按年齡倒序排序
GET /lib3/user/_search?q=interests:changge&sort=ag:desc
7.2 term 查詢和 terms 查詢
term query會去倒排索引中尋找確切的term锭硼,它并不知道分詞器的存在房资。這種查詢適合keyword 、numeric檀头、date轰异。
term:查詢某個字段里含有某個關(guān)鍵詞的文檔
GET /lib3/_search/
{
"query": {
"term": {
"interests": "changge"
}
}
}
terms:查詢某個字段里含有多個關(guān)鍵詞的文檔,只要有一個匹配就會被查出來
GET /lib3/_search
{
"query": {
"terms": {
"interests": [
"hejiu",
"changge"
]
}
}
}
7.3 控制查詢返回的數(shù)量
from:從哪一個文檔開始
size:需要的個數(shù)
GET /lib3/_search
{
"from": 0,
"size": 2,
"query": {
"terms": {
"interests": [
"hejiu",
"changge"
]
}
}
}
7.4 返回版本號
version: true
GET /lib3/_search
{
"version": true,
"query": {
"terms": {
"interests": [
"hejiu",
"changge"
]
}
}
}
7.5 match 查詢
match query 知道分詞器的存在暑始,會對 filed 進行分詞操作搭独,然后再查詢
會對 name 進行分詞,會查出來兩個廊镜,而 term 會把 zhaoliu lisi
看成一個詞牙肝,一個都查不出來
GET /lib3/_search
{
"query": {
"match": {
"name": "zhaoliu lisi"
}
}
}
match_all:查詢所有文檔
GET /lib3/_search
{
"query": {
"match_all": {}
}
}
multi_match:可以指定多個字段
在 interests 和 name 中查詢 lisi
GET /lib3/_search
{
"query": {
"multi_match": {
"query": "lisi",
"fields": [
"interests",
"name"
]
}
}
}
match_phrase:短語匹配查詢
查詢和短語一模一樣的文檔(標點、空格可以不一樣)
GET lib3/_search
{
"query": {
"match_phrase": {
"interests": "shuijiao,chifan,fadai"
}
}
}
7.6 指定返回的字段
GET /lib3/_search
{
"_source": [
"address",
"name"
],
"query": {
"match": {
"interests": "changge"
}
}
}
7.7 控制加載的字段
和上面差不多
GET /lib3/_search
{
"query": {
"match_all": {}
},
"_source": {
"includes": [
"name",
"address"
],
"excludes": [
"age",
"birthday"
]
}
}
使用通配符 *
GET /lib3/_search
{
"_source": {
"includes": "addr*",
"excludes": [
"name",
"bir*"
]
},
"query": {
"match_all": {}
}
}
7.8 排序
使用sort實現(xiàn)排序 :
desc:降序,asc:升序
GET /lib3/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"age": {
"order": "asc"
}
}
]
}
7.9 前綴匹配查詢
GET /lib3/_search
{
"query": {
"match_phrase_prefix": {
"name": {
"query": "zhao"
}
}
}
}
7.10 范圍查詢
range:實現(xiàn)范圍查詢
參數(shù):from,to,include_lower,include_upper,boost
include_lower:是否包含范圍的左邊界配椭,默認是true
include_upper:是否包含范圍的右邊界虫溜,默認是true
GET /lib3/_search
{
"query": {
"range": {
"birthday": {
"from": "1990-10-10",
"to": "2018-05-01"
}
}
}
}
7.11 wildcard 查詢
允許使用通配符* 和 ?來進行查詢
*代表0個或多個字符
?代表任意一個字符
GET /lib3/_search
{
"query": {
"wildcard": {
"name": "li?i"
}
}
}
7.12 fuzzy 模糊查詢
- value:查詢的關(guān)鍵字
- boost:查詢的權(quán)值颂郎,默認值是1.0
- min_similarity:設(shè)置匹配的最小相似度吼渡,默認值為0.5,對于字符串乓序,取值為0-1(包括0和1);對于數(shù)值,取值可能大于1;對于日期型取值為1d,1m等坎背,1d就代表1天
- prefix_length:指明區(qū)分詞項的共同前綴長度替劈,默認是0
- max_expansions:查詢中的詞項可以擴展的數(shù)目,默認可以無限大
這里 changge 寫成了 chagge 還是能查出來
GET /lib3/_search
{
"query": {
"fuzzy": {
"interests": "chagge"
}
}
}
GET /lib3/_search
{
"query": {
"fuzzy": {
"interests": {
"value": "chagge"
}
}
}
}
7.13 高亮搜索結(jié)果
高亮的結(jié)果會被加上 <em> 標簽得滤,放在網(wǎng)頁上就是高亮了
GET /lib3/_search
{
"query": {
"match": {
"interests": "changge"
}
},
"highlight": {
"fields": {
"interests": {}
}
}
}
8. 基本查詢(中文)
準備數(shù)據(jù)陨献,這次指定中文分析器
ik 帶有兩個分詞器
ik_max_word:會將文本做最細粒度的拆分,盡可能多的拆分詞語
ik_smart:會做粗細粒度的拆分懂更,已經(jīng)被分出的詞語將不會再次被其他詞語占有
PUT /lib3
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 0
},
"mappings": {
"properties": {
"name": {
"type": "text",
"analyzer": "ik_max_word"
},
"address": {
"type": "text",
"analyzer": "ik_max_word"
},
"age": {
"type": "integer"
},
"interests": {
"type": "text",
"analyzer": "ik_max_word"
},
"birthday": {
"type": "date"
}
}
}
}
PUT /lib3/_doc/1
{
"name": "李四",
"address": "北京海淀區(qū)清河鎮(zhèn)",
"age": 23,
"birthday": "1998-10-12",
"interests": "喜歡鍛煉眨业、喝酒、唱歌"
}
PUT /lib3/_doc/2
{
"name": "王五",
"address": "黑龍江省鐵嶺",
"age": 24,
"birthday": "1996-10-12",
"interests": "喜歡打籃球沮协、跑步龄捡、唱歌"
}
PUT /lib3/_doc/3
{
"name": "李六",
"address": "北京海淀區(qū)清河鎮(zhèn)",
"age": 26,
"birthday": "1999-10-12",
"interests": "喜歡吃飯、睡覺慷暂、發(fā)呆"
}
查詢和英文的差不多聘殖,這里給一個查詢示例:
GET /lib3/_search
{
"query": {
"terms": {
"interests": [
"唱歌",
"喝酒"
]
}
}
}
9. 過濾查詢(Filter)
filter 是不計算相關(guān)性的,同時可以cache行瑞。因此奸腺,filter速度要快于query。
數(shù)據(jù)準備
PUT /lib4
POST /lib4/_bulk
{"index": {"_id": 1}}
{"price": 40,"itemID": "ID100123"}
{"index": {"_id": 2}}
{"price": 50,"itemID": "ID100124"}
{"index": {"_id": 3}}
{"price": 25,"itemID": "ID100124"}
{"index": {"_id": 4}}
{"price": 30,"itemID": "ID100125"}
{"index": {"_id": 5}}
{"price": null,"itemID": "ID100127"}
9.1 簡單過濾查詢
GET /lib4/_search
{
"post_filter": {
"terms": {
"price": [
25,
40
]
}
}
}
9.2 bool 過濾查詢
可以實現(xiàn)組合過濾查詢
格式:
{
"bool": {
"must": [],
"should": [],
"must_not": []
}
}
- must:必須滿足的條件 -- and
- should:可以滿足也可以不滿足的條件 -- or
- must_not:不需要滿足的條件 -- not
GET /lib4/_search
{
"post_filter": {
"bool": {
"should": [
{
"term": {
"price": 25
}
},
{
"term": {
"itemID": "id100123"
}
}
],
"must_not": {
"term": {
"price": 30
}
}
}
}
}
嵌套使用 bool
GET /lib4/_search
{
"post_filter": {
"bool": {
"should": [
{
"term": {
"itemID": "id100123"
}
},
{
"bool": {
"must": [
{
"term": {
"itemID": "id100124"
}
},
{
"term": {
"price": 40
}
}
]
}
}
]
}
}
}
9.3 范圍過濾
gt: >
lt: <
gte: >=
lte: <=
GET /lib4/_search
{
"post_filter": {
"range": {
"price": {
"gt": 25,
"lt": 50
}
}
}
}
9.4 非空過濾
GET /lib4/_search
{
"query": {
"bool": {
"filter": {
"exists": {
"field": "price"
}
}
}
}
}
GET /lib4/_search
{
"query": {
"constant_score": {
"filter": {
"exists": {
"field": "price"
}
}
}
}
}
9.5 過濾器緩存
ElasticSearch 提供了一種特殊的緩存血久,即過濾器緩存(filter cache)突照,用來存儲過濾器的結(jié)果,被緩存的過濾器并不需要消耗過多的內(nèi)存(因為它們只存儲了哪些文檔能與過濾器相匹配的相關(guān)信息)氧吐,而且可供后續(xù)所有與之相關(guān)的查詢重復(fù)使用讹蘑,從而極大地提高了查詢性能。
ElasticSearch并不是默認緩存所有過濾器副砍,以下過濾器默認不緩存:
- numeric_range
- script
- geo_bbox
- geo_distance
- geo_distance_range
- geo_polygon
- geo_shape
- and
- or
- not
10. 聚合查詢
sum
GET /lib4/_search
{
"size": 0,
"aggs": {
"price_of_sum": {
"sum": {
"field": "price"
}
}
}
}
min
GET /lib4/_search
{
"size": 0,
"aggs": {
"price_of_min": {
"min": {
"field": "price"
}
}
}
}
max
GET /lib4/_search
{
"size": 0,
"aggs": {
"price_of_max": {
"max": {
"field": "price"
}
}
}
}
avg
GET /lib4/_search
{
"size": 0,
"aggs": {
"price_of_avg": {
"avg": {
"field": "price"
}
}
}
}
cardinality 基數(shù)衔肢,互不相同數(shù)據(jù)的個數(shù)
GET /lib4/_search
{
"size": 0,
"aggs": {
"price_of_cardi": {
"cardinality": {
"field": "price"
}
}
}
}
terms 分組
GET /lib4/_search
{
"size": 0,
"aggs": {
"price_group_by": {
"terms": {
"field": "price"
}
}
}
}
練習(xí):對那些有唱歌興趣的用戶按年齡分組
GET /lib3/_search
{
"query": {
"match": {
"interests": "changge"
}
},
"size": 0,
"aggs": {
"age_group_by": {
"terms": {
"field": "age",
"order": {
"avg_of_age": "desc"
}
},
"aggs": {
"avg_of_age": {
"avg": {
"field": "age"
}
}
}
}
}
11. 復(fù)合查詢
復(fù)合查詢就是把各種查詢條件組合在一起,也叫組合查詢
11.1 bool 查詢
接收以下參數(shù):
- must:
文檔必須匹配這些條件才能被包含進來豁翎。 - must_not:
文檔必須不匹配這些條件才能被包含進來角骤。 - should:
如果滿足這些語句中的任意語句,將增加 _score,否則邦尊,無任何影響背桐。它們主要用于修正每個文檔的相關(guān)性得分。 - filter:
必須匹配蝉揍,但它以不評分链峭、過濾模式來進行。這些語句對評分沒有貢獻又沾,只是根據(jù)過濾標準來排除或包含文檔弊仪。
相關(guān)性得分是如何組合的?
每一個子查詢都獨自地計算文檔的相關(guān)性得分杖刷。一旦他們的得分被計算出來励饵, bool 查詢就將這些得分進行合并并且返回一個代表整個布爾操作的得分。
下面的查詢用于查找 title 字段匹配 how to make millions 并且不被標識為 spam 的文檔滑燃。那些被標識為 starred 或在2014之后的文檔役听,將比另外那些文檔擁有更高的排名。如果 兩者 都滿足表窘,那么它排名將更高:
{
"bool": {
"must": { "match": { "title": "how to make millions" }},
"must_not": { "match": { "tag": "spam" }},
"should": [
{ "match": { "tag": "starred" }},
{ "range": { "date": { "gte": "2014-01-01" }}}
]
}
}
如果沒有 must 語句典予,那么至少需要能夠匹配其中的一條 should 語句。但乐严,如果存在至少一條 must 語句瘤袖,則對 should 語句的匹配沒有要求。
如果我們不想因為文檔的時間而影響得分麦备,可以用 filter 語句來重寫前面的例子:
{
"bool": {
"must": { "match": { "title": "how to make millions" }},
"must_not": { "match": { "tag": "spam" }},
"should": [
{ "match": { "tag": "starred" }}
],
"filter": {
"range": { "date": { "gte": "2014-01-01" }}
}
}
}
通過將 range 查詢移到 filter 語句中孽椰,我們將它轉(zhuǎn)成不評分的查詢,將不再影響文檔的相關(guān)性排名凛篙。由于它現(xiàn)在是一個不評分的查詢黍匾,可以使用各種對 filter 查詢有效的優(yōu)化手段來提升性能。
bool 查詢本身也可以被用做不評分的查詢呛梆。簡單地將它放置到 filter 語句中并在內(nèi)部構(gòu)建布爾邏輯:
{
"bool": {
"must": { "match": { "title": "how to make millions" }},
"must_not": { "match": { "tag": "spam" }},
"should": [
{ "match": { "tag": "starred" }}
],
"filter": {
"bool": {
"must": [
{ "range": { "date": { "gte": "2014-01-01" }}},
{ "range": { "price": { "lte": 29.99 }}}
],
"must_not": [
{ "term": { "category": "ebooks" }}
]
}
}
}
}
11.2 constant_score 查詢
它將一個不變的常量評分應(yīng)用于所有匹配的文檔锐涯。它被經(jīng)常用于你只需要執(zhí)行一個 filter 而沒有其它查詢(例如,評分查詢)的情況下填物。
{
"constant_score": {
"filter": {
"term": { "category": "ebooks" }
}
}
}
term 查詢被放置在 constant_score 中纹腌,轉(zhuǎn)成不評分的filter。這種方式可以用來取代只有 filter 語句的 bool 查詢滞磺。