目錄結構:
---------------------------------------分割線:正文--------------------------------------------------------
1、Doug Cutting
(1)建立了Lucene,(es與solr基於Lucene), 開源且功能為一套資訊檢索工具包,jar包
(2)實現了NDFS(分散式檔案儲存系統)基於Google的GFS系統
(3)將NDFS與MapReduce升級改造,重新命名為Hadoop,hadoop之父
(4)基於Google的BigTable,實現了HBase
2、ElasticSearch概述
(1)概念:開源的分散式全文檢索引擎
(2)優點:近乎實時儲存、檢索資料,擴充套件性好,可擴充套件上百臺伺服器,處理PB級別的資料,基於Lucene核心,通過RestFul API使全文搜尋變得簡單
(3)誰在使用:維基百科,搜狐新聞,Github等等
3、ES與solr的區別
(1)ES是RestFul API,而Solr是WebService API
(2)單純已有的資料搜尋,solr更快
(3)建立索引後的資料,Solr會產生io阻塞,es有明顯的優勢
(4)資料量增加,Solr的搜尋效率會變低,es不受影響
宣告:安裝條件,JDK1.8+
1、es下載:
(1)es客戶端:https://www.elastic.co/cn/downloads/elasticsearch
(2)ik分詞器:https://github.com/medcl/elasticsearch-analysis-ik/releases
(3)kibana:https://www.elastic.co/cn/downloads/kibana
(4)head外掛:https://github.com/mobz/elasticsearch-head/archive/master.zip
(5)chrome-es外掛:https://github.com/mobz/elasticsearch-head/blob/master/crx/es-head.crx
2、es客戶端windows安裝
(1)安裝步驟
elasticsearch-7.12.1-windows-x86_64.zip 解壓即可。
(2)相關檔案
bin:啟動檔案
config:配置檔案
- - log4j2.properties:日誌配置
- - elasticsearch.yml:es配置檔案,預設9200埠
- - jvm.options:java虛擬機器相關配置
lib:相關jar包
modules:功能模組
plugins:外掛!如ik分詞器等
logs:日誌
(3)啟動es
雙擊bin目錄下elasticsearch.bat
啟動成功,預設訪問9200埠
瀏覽器訪問:http://127.0.0.1:9200/ 返回相關配置資訊
3、安裝視覺化介面:es head的外掛
(1)解壓縮:elasticsearch-head-master.zip
(2)安裝node.js:https://nodejs.org/en/
cmd:node -v驗證安裝成功
(3)安裝cnpm:
cmd安裝淘寶映象:npm install -g cnpm -registry=https://registry.npm.taobao.org
cnpm -v驗證安裝成功
(4)安裝依賴:
進入D:\elasticsearch\elasticsearch-head-master目錄;執行cnpm install;
(5)執行npm run start啟動npm
(6)瀏覽器訪問:http://localhost:9100
由於跨域無法訪問:
(7)配置可跨域
配置conf下elasticsearch.yml新增配置
http.cors.enabled: true
http.cors.allow-origin: "*"
重啟es服務,再次訪問,叢集連線正常
4、Kibana安裝
(1)Kibana安裝的版本要與es版本對應:
(2)啟動測試:執行bin下kibana.bat並測試對應的介面
(3)開發工具 http://localhost:5601
(4)配置中文:config下kibana.yml,新增配置並重啟服務
i18n.locale: "zh-CN"
1、elasticsearch是面向文件的(一切都是json),與關係型資料庫的對比
RelationDB -> Elasticsearch
資料庫(database) -> 索引(indices)
表(tables) -> types(慢慢會被棄用)
行(rows) -> documents
欄位(columns) -> fields
2、es物理設計:
elasticsearch在後臺把每個索引劃分成多個分片,每個分片在叢集中的不同的服務間遷移。
預設的叢集名就是elasticsearch
3、邏輯設計:
(1)文件:最小單位,即一條條資料
(2)型別:text、date等型別
(3)索引:資料庫
4、es欄位型別:
text:會被分詞器解析
keyword:不會被分詞器解析
1、分詞:
把一段中文或別的劃分為一個個關鍵字,我們在搜尋時候會把自己的資訊進行分詞,預設的中文分詞器將每個字看成一個詞,我們需安裝使用中文分詞器ik來解決
2、安裝ik分詞器:
(1)下載:https://github.com/medcl/elasticsearch-analysis-ik/releases
(2)安裝:elasticsearch-analysis-ik-7.12.1.zip放入elasticsearch-7.12.1\plugins目錄下解壓縮即可使用:
(3)重啟觀察ES,載入外掛成功
[2021-05-12T23:00:05,420][INFO ][o.e.p.PluginsService ] [DESKTOP-GIEVO4Q] loaded plugin [analysis-ik]
[2021-05-12T23:00:05,615][INFO ][o.e.e.NodeEnvironment ] [DESKTOP-GIEVO4Q] using [1] data paths, mounts [[杞歡 (D:)]], net usable_space [179.3gb], net total_space [300.7gb], types [NTFS]
(4)驗證通過:elasticsearch-plugin list
D:\elasticsearch\elasticsearch-7.12.1\bin>elasticsearch-plugin list
"warning: usage of JAVA_HOME is deprecated, use ES_JAVA_HOME"
Future versions of Elasticsearch will require Java 11; your Java version from [C:\Program Files\Java\jdk1.8.0_271\jre] does not meet this requirement. Consider switching to a distribution of Elasticsearch with a bundled JDK. If you are already using a distribution with a bundled JDK, ensure the JAVA_HOME environment variable is not set.
ik
3、使用kibana進行測試
啟動kibana進入控制檯進行測試
檢視不同的分詞器效果
(1)ik_smart
GET _analyze
{
"analyzer": "ik_smart",
"text":"軟體工程師"
}
檢視執行結果:
{
"tokens" : [
{
"token" : "軟體",
"start_offset" : 0,
"end_offset" : 2,
"type" : "CN_WORD",
"position" : 0
},
{
"token" : "工程師",
"start_offset" : 2,
"end_offset" : 5,
"type" : "CN_WORD",
"position" : 1
}
]
}
(2)ik_max_word
GET _analyze
{
"analyzer": "ik_max_word",
"text":"軟體工程師"
}
檢視執行結果:
{
"tokens" : [
{
"token" : "軟體工程",
"start_offset" : 0,
"end_offset" : 4,
"type" : "CN_WORD",
"position" : 0
},
{
"token" : "軟體",
"start_offset" : 0,
"end_offset" : 2,
"type" : "CN_WORD",
"position" : 1
},
{
"token" : "工程師",
"start_offset" : 2,
"end_offset" : 5,
"type" : "CN_WORD",
"position" : 2
},
{
"token" : "工程",
"start_offset" : 2,
"end_offset" : 4,
"type" : "CN_WORD",
"position" : 3
},
{
"token" : "師",
"start_offset" : 4,
"end_offset" : 5,
"type" : "CN_CHAR",
"position" : 4
}
]
}
4、將加入自己需要的詞加到分詞器的字典中
開啟:elasticsearch-7.12.1\plugins\ik\config\IKAnalyzer.cfg.xml,配置<entry key="ext_dict"></entry>內新增欄位對映
(1)配置前
GET _analyze
{
"analyzer": "ik_max_word",
"text":"我的媽"
}
檢視執行結果:
{
"tokens" : [
{
"token" : "我",
"start_offset" : 0,
"end_offset" : 1,
"type" : "CN_CHAR",
"position" : 0
},
{
"token" : "的",
"start_offset" : 1,
"end_offset" : 2,
"type" : "CN_CHAR",
"position" : 1
},
{
"token" : "媽",
"start_offset" : 2,
"end_offset" : 3,
"type" : "CN_CHAR",
"position" : 2
}
]
}
(2)配置
<entry key="ext_dict">my.dic</entry>
同目錄下新增my.dic -> 我的媽
(3)配置後重啟es,控制檯
{
"tokens" : [
{
"token" : "我的媽",
"start_offset" : 0,
"end_offset" : 3,
"type" : "CN_WORD",
"position" : 0
}
]
}
檢視執行結果:
{
"tokens" : [
{
"token" : "我的媽",
"start_offset" : 0,
"end_offset" : 3,
"type" : "CN_WORD",
"position" : 0
}
]
}
1、基本Rest命令:
PUT | localhost:9200/索引名稱/型別名稱/文件id | 建立文件(指定文件id)
POST | localhost:9200/索引名稱/型別名稱 | 建立文件(隨機文件id)
POST | localhost:9200/索引名稱/型別名稱/文件id/_update | 修改文件
DELETE | localhost:9200/索引名稱/型別名稱/文件id | 刪除文件
GET | localhost:9200/索引名稱/型別名稱/文件id | 查詢文件通過文件id
POST | localhost:9200/索引名稱/型別名稱/文件id/_search | 查詢所有文件
2、基礎測試-建立索引
建立一個索引:PUT /索引名/~型別名~/文件id
PUT /test1/type1/1
{
"name":"小白學es",
"age":3
}
檢視響應,完成自動增加了索引,類似資料庫
#! [types removal] Specifying types in document index requests is deprecated, use the typeless endpoints instead (/{index}/_doc/{id}, /{index}/_doc, or /{index}/_create/{id}).
{
"_index" : "test1",
"_type" : "type1",
"_id" : "1",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}
3、基本資料型別
(1)字串型別:text、keyword
(2)數值型別:long、integer、short、byte、double、half float、scaled、float
(3)日期型別:date
(4)te布林型別:boolean
(5)二進位制型別:binary
4、基礎測試-建立並指定索引型別
PUT /test2
{
"mappings":{
"properties": {
"name":{
"type":"text"
},
"age":{
"type":"long"
},
"birthday":{
"type":"date"
}
}
}
}
檢視執行結果
{
"acknowledged" : true,
"shards_acknowledged" : true,
"index" : "test2"
}
5、 基礎測試-建立/檢視預設資訊
(1)建立預設索引即文件
PUT /test3/_doc/1
{
"name":"小白學es",
"age":18,
"bithday":"1997-07-07"
}
檢視執行結果
{
"_index" : "test3",
"_type" : "_doc",
"_id" : "1",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}
外掛檢視
(2)檢視索引,預設配置欄位型別!
GET test3
執行結果:
{
"test3" : {
"aliases" : { },
"mappings" : {
"properties" : {
"age" : {
"type" : "long"
},
"bithday" : {
"type" : "date"
},
"name" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
},
"settings" : {
"index" : {
"routing" : {
"allocation" : {
"include" : {
"_tier_preference" : "data_content"
}
}
},
"number_of_shards" : "1",
"provided_name" : "test3",
"creation_date" : "1621064937104",
"number_of_replicas" : "1",
"uuid" : "f_-oPx65RwOk846CysvHRQ",
"version" : {
"created" : "7120199"
}
}
}
}
}
6、擴充套件,檢視叢集/索引資訊:
檢視叢集狀態:
GET _cat/health
執行結果:
1621065190 07:53:10 elasticsearch yellow 1 1 9 9 0 0 2 0 - 81.8%
檢視索引版本資訊等:
GET _cat/indices?v
執行結果:
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
green open .kibana_7.12.1_001 aGaAAOZTSQyk_0ZU_lOXsg 1 0 54 23 4.2mb 4.2mb
yellow open test2 3f9X5bcAQXKciY56Il5nfA 1 1 0 0 208b 208b
yellow open test3 f_-oPx65RwOk846CysvHRQ 1 1 1 0 4.2kb 4.2kb
green open .apm-custom-link ZyIwiavFSJSFTbh2cMd8Tg 1 0 0 0 208b 208b
green open .apm-agent-configuration FD1qwkXwTTaCT6orvViPRg 1 0 0 0 208b 208b
green open .kibana_task_manager_7.12.1_001 MIUHf-m7S_e8XrjZMduTpA 1 0 9 272 286.7kb 286.7kb
green open .kibana-event-log-7.12.1-000001 qPBR8ea4Th24CnhfxKa3Sg 1 0 6 0 32.6kb 32.6kb
green open .tasks uwcYsws9QkqK1CXKQiNI0Q 1 0 10 0 50kb 50kb
7、基礎測試-修改索引/文件
(1)直接覆蓋:PUT
PUT /test3/_doc/1
{
"name":"小白學es2",
"age":18,
"bithday":"1997-07-07"
}
執行結果:version+1,result為updated
{
"_index" : "test3",
"_type" : "_doc",
"_id" : "1",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 1,
"_primary_term" : 1
}
外掛檢視結果:
(2)update更新:POST
POST /test3/_doc/1/_update
{
"doc":{
"name":"小白學es3"
}
}
執行結果:version+1,result為updated
#! [types removal] Specifying types in document update requests is deprecated, use the endpoint /{index}/_update/{id} instead.
{
"_index" : "test3",
"_type" : "_doc",
"_id" : "1",
"_version" : 3,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 2,
"_primary_term" : 1
}
外掛檢視結果:
8、基礎測試-刪除索引
(1)刪除索引
DELETE test1
檢視執行結果:
{
"acknowledged" : true
}
(2)刪除索引中文件
DELETE test3/_doc/1
檢視執行結果:
{
"_index" : "test3",
"_type" : "_doc",
"_id" : "1",
"_version" : 4,
"result" : "deleted",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 3,
"_primary_term" : 1
}
1、新增資料:PUT
PUT /xiaobai/user/1
{
"name":"小白",
"age":30,
"desc":"一頓操作猛如虎,一看工資2500",
"tags":["技術宅","直男"]
}
檢視執行結果:
#! [types removal] Specifying types in document index requests is deprecated, use the typeless endpoints instead (/{index}/_doc/{id}, /{index}/_doc, or /{index}/_create/{id}).
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "1",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}
外掛檢視:
同樣的方法新增一些資料:
2、獲取資料:GET
GET xiaobai/user/1
檢視執行結果:
#! [types removal] Specifying types in document get requests is deprecated, use the /{index}/_doc/{id} endpoint instead.
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "1",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true,
"_source" : {
"name" : "小白",
"age" : "30",
"desc" : "一頓操作猛如虎,一看工資2500",
"tags" : [
"技術宅",
"直男"
]
}
}
3、更新資料:PUT/POST
(1)PUT修改:全量欄位更新
1號資料name:小白 -> 白神
PUT /xiaobai/user/1
{
"name":"白神",
"age":"30",
"desc":"一頓操作猛如虎,一看工資2500",
"tags":["技術宅","直男"]
}
檢視執行結果:
#! [types removal] Specifying types in document index requests is deprecated, use the typeless endpoints instead (/{index}/_doc/{id}, /{index}/_doc, or /{index}/_create/{id}).
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "1",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 5,
"_primary_term" : 2
}
(2)POST _update:指定欄位更新(推薦使用)
POST /xiaobai/user/1/_update
{
"doc":{
"name":"小白java"
}
}
檢視執行結果:
#! [types removal] Specifying types in document update requests is deprecated, use the endpoint /{index}/_update/{id} instead.
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "1",
"_version" : 5,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 8,
"_primary_term" : 2
}
4、簡單的搜尋:GET _searcher
text型別可以根據欄位分詞搜尋,keyword關鍵詞不會處理分詞器
GET /xiaobai/user/_search?q=name:小白
檢視執行結果:
#! [types removal] Specifying types in search requests is deprecated.
{
"took" : 32,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 3,
"relation" : "eq"
},
"max_score" : 1.9252907,
"hits" : [
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "1",
"_score" : 1.9252907,
"_source" : {
"name" : "小白",
"age" : "30",
"desc" : "一頓操作猛如虎,一看工資2500",
"tags" : [
"技術宅",
"直男"
]
}
},
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "2",
"_score" : 0.53899646,
"_source" : {
"name" : "小黑",
"age" : "32",
"desc" : "腹黑男豬腳",
"tags" : [
"旅遊",
"渣男",
"遊戲宅"
]
}
},
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "5",
"_score" : 0.53899646,
"_source" : {
"name" : "小王",
"age" : "32",
"desc" : "社會性死亡",
"tags" : [
"技術宅",
"暖男",
"中年危機"
]
}
}
]
}
}
5、複雜操作搜尋: _searcher match - 分詞模糊匹配
{
"query":{
"match": {
"name": "鑽石王老五"
}
}
}
檢視執行結果:
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 4,
"relation": "eq"
},
"max_score": 3.0311832,
"hits": [
{
"_index": "xiaobai",
"_type": "user",
"_id": "6",
"_score": 3.0311832,
"_source": {
"name": "鑽石王老五",
"age": "32",
"desc": "社會性死亡",
"tags": [
"技術宅",
"暖男",
"中年危機"
]
}
},
{
"_index": "xiaobai",
"_type": "user",
"_id": "4",
"_score": 1.9277248,
"_source": {
"name": "王五",
"age": "30",
"desc": "正宗青子",
"tags": [
"青年",
"吃貨",
"旅遊",
"胖子"
]
}
},
{
"_index": "xiaobai",
"_type": "user",
"_id": "7",
"_score": 1.6832076,
"_source": {
"name": "鑽石李老四",
"age": "32",
"desc": "社會性死亡",
"tags": [
"技術宅",
"暖男",
"中年危機"
]
}
},
{
"_index": "xiaobai",
"_type": "user",
"_id": "5",
"_score": 1.2623059,
"_source": {
"name": "鑽石123",
"age": "32",
"desc": "社會性死亡",
"tags": [
"技術宅",
"暖男",
"中年危機"
]
}
}
]
}
}
6、複雜操作搜尋: _searcher match_phrase - 完整模糊匹配
GET /xiaobai/user/_search
{
"query":{
"match_phrase": {
"name": "鑽石王老五"
}
}
}
檢視執行結果:
#! [types removal] Specifying types in search requests is deprecated.
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 3.0311837,
"hits" : [
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "6",
"_score" : 3.0311837,
"_source" : {
"name" : "鑽石王老五",
"age" : "32",
"desc" : "社會性死亡",
"tags" : [
"技術宅",
"暖男",
"中年危機"
]
}
}
]
}
}
7、複雜操作搜尋: _searcher term - 完成精確匹配
GET xiaobai/user/_search
{
"query":{
"term": {
"name.keyword": "鑽石王老五"
}
}
}
檢視執行結果:
#! [types removal] Specifying types in search requests is deprecated.
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.2039728,
"hits" : [
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "3",
"_score" : 1.2039728,
"_source" : {
"name" : "鑽石王老五",
"age" : "19",
"desc" : "社會性死亡",
"tags" : [
"技術宅",
"暖男"
]
}
}
]
}
}
8、複雜操作搜尋: _searcher _source - 過濾展示結果
GET /xiaobai/user/_search
{
"query":{
"match_phrase": {
"name": "鑽石王老五"
}
},
"_source":["name","desc"]
}
檢視執行結果:
#! [types removal] Specifying types in search requests is deprecated.
{
"took" : 11,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 3.0311837,
"hits" : [
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "6",
"_score" : 3.0311837,
"_source" : {
"name" : "鑽石王老五",
"desc" : "社會性死亡"
}
}
]
}
}
9、複雜操作搜尋: _searcher sort - 排序(desc/asc)
GET xiaobai/user/_search
{
"query":{
"match_phrase": {
"name": "鑽石"
}
},
"sort":[
{
"age":{
"order":"desc"
}
}
]
}
檢視執行結果:
#! [types removal] Specifying types in search requests is deprecated.
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 3,
"relation" : "eq"
},
"max_score" : null,
"hits" : [
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "2",
"_score" : null,
"_source" : {
"name" : "鑽石李老四",
"age" : "32",
"desc" : "社會性死亡",
"tags" : [
"技術宅",
"暖男",
"中年危機"
]
},
"sort" : [
32
]
},
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "4",
"_score" : null,
"_source" : {
"name" : "鑽石123",
"age" : "28",
"desc" : "廢物一個",
"tags" : [
"技術宅"
]
},
"sort" : [
28
]
},
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "3",
"_score" : null,
"_source" : {
"name" : "鑽石王老五",
"age" : "19",
"desc" : "社會性死亡",
"tags" : [
"技術宅",
"暖男"
]
},
"sort" : [
19
]
}
]
}
}
10、複雜操作搜尋: _searcher from size - 分頁查詢
GET xiaobai/user/_search
{
"query":{
"match_phrase": {
"name": "鑽石"
}
},
"from":0,
"size":2
}
檢視執行結果:
#! [types removal] Specifying types in search requests is deprecated.
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 3,
"relation" : "eq"
},
"max_score" : 0.77691567,
"hits" : [
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "4",
"_score" : 0.77691567,
"_source" : {
"name" : "鑽石123",
"age" : "28",
"desc" : "廢物一個",
"tags" : [
"技術宅"
]
}
},
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "2",
"_score" : 0.62774795,
"_source" : {
"name" : "鑽石李老四",
"age" : "32",
"desc" : "社會性死亡",
"tags" : [
"技術宅",
"暖男",
"中年危機"
]
}
}
]
}
}
11、複雜操作搜尋: _searcher bool - 聯合查詢 -must - 所有條件均符合
GET xiaobai/user/_search
{
"query":{
"bool": {
"must":[{
"match":{
"name":"鑽石王老五"
}
},
{
"match":{
"age":28
}
}
]
}
}
}
檢視執行結果:
#! [types removal] Specifying types in search requests is deprecated.
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.7769157,
"hits" : [
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "4",
"_score" : 1.7769157,
"_source" : {
"name" : "鑽石123",
"age" : "28",
"desc" : "廢物一個",
"tags" : [
"技術宅"
]
}
}
]
}
}
12、複雜操作搜尋:_searcher bool - 聯合查詢 - should - 滿足任意一個條件
GET xiaobai/user/_search
{
"query":{
"bool": {
"should":[{
"match":{
"name":"小白"
}
},
{
"match":{
"age":28
}
}
]
}
}
}
檢視執行結果:
#! [types removal] Specifying types in search requests is deprecated.
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 2.9761126,
"hits" : [
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "1",
"_score" : 2.9761126,
"_source" : {
"name" : "小白",
"age" : 30,
"desc" : "一頓操作猛如虎,一看工資2500",
"tags" : [
"技術宅",
"直男"
]
}
},
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "4",
"_score" : 1.0,
"_source" : {
"name" : "鑽石123",
"age" : "28",
"desc" : "廢物一個",
"tags" : [
"技術宅"
]
}
}
]
}
}
13、複雜操作搜尋:_searcher bool - 聯合查詢 - must_not - 不滿足
GET xiaobai/user/_search
{
"query":{
"bool": {
"must_not":[{
"match":{
"name":"小白"
}
},
{
"match":{
"age":28
}
}
]
}
}
}
檢視執行結果:
#! [types removal] Specifying types in search requests is deprecated.
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 0.0,
"hits" : [
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "2",
"_score" : 0.0,
"_source" : {
"name" : "鑽石李老四",
"age" : "32",
"desc" : "社會性死亡",
"tags" : [
"技術宅",
"暖男",
"中年危機"
]
}
},
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "3",
"_score" : 0.0,
"_source" : {
"name" : "鑽石王老五",
"age" : "19",
"desc" : "社會性死亡",
"tags" : [
"技術宅",
"暖男"
]
}
}
]
}
}
14、複雜操作搜尋:_searcher bool - 聯合查詢 - filter - 過濾
gt(>) gte(>=) lt(<) lte(<=)
GET xiaobai/user/_search
{
"query":{
"bool": {
"must":[{
"match":{
"name":"鑽石"
}
}
],"filter":
{"range": {
"age": {
"gte": 10,
"lte": 30
}
}}
}
}
}
檢視執行結果:
#! [types removal] Specifying types in search requests is deprecated.
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 0.77691567,
"hits" : [
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "4",
"_score" : 0.77691567,
"_source" : {
"name" : "鑽石123",
"age" : "28",
"desc" : "廢物一個",
"tags" : [
"技術宅"
]
}
},
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "3",
"_score" : 0.62774795,
"_source" : {
"name" : "鑽石王老五",
"age" : "19",
"desc" : "社會性死亡",
"tags" : [
"技術宅",
"暖男"
]
}
}
]
}
}
15、複雜操作搜尋:_searcher match - 匹配多個標籤分詞(空格隔開)
GET xiaobai/user/_search
{
"query":{
"match": {
"tags":"男 技術宅"
}
}
}
檢視執行結果:
#! [types removal] Specifying types in search requests is deprecated.
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 4,
"relation" : "eq"
},
"max_score" : 0.6987428,
"hits" : [
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "1",
"_score" : 0.6987428,
"_source" : {
"name" : "小白",
"age" : 30,
"desc" : "一頓操作猛如虎,一看工資2500",
"tags" : [
"技術宅",
"直男"
]
}
},
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "3",
"_score" : 0.6987428,
"_source" : {
"name" : "鑽石王老五",
"age" : "19",
"desc" : "社會性死亡",
"tags" : [
"技術宅",
"暖男"
]
}
},
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "2",
"_score" : 0.5337937,
"_source" : {
"name" : "鑽石李老四",
"age" : "32",
"desc" : "社會性死亡",
"tags" : [
"技術宅",
"暖男",
"中年危機"
]
}
},
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "4",
"_score" : 0.38828292,
"_source" : {
"name" : "鑽石123",
"age" : "28",
"desc" : "廢物一個",
"tags" : [
"技術宅"
]
}
}
]
}
}
16、複雜操作搜尋:_searcher bool term - 多個條件精確匹配
GET xiaobai/user/_search
{
"query":{
"bool": {
"should":[{
"term":{
"name":"test01"
}
},
{
"term":{
"name":"test02"
}
}
]}
}
}
檢視執行結果:
#! [types removal] Specifying types in search requests is deprecated.
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.8809632,
"hits" : [
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "4",
"_score" : 1.8809632,
"_source" : {
"name" : "test01",
"age" : "28",
"desc" : "廢物一個",
"tags" : [
"技術宅"
]
}
},
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "5",
"_score" : 1.8809632,
"_source" : {
"name" : "test02",
"age" : "28",
"desc" : "廢物一個",
"tags" : [
"技術宅"
]
}
}
]
}
}
17、複雜操作搜尋:_searcher highlight - (自定義高亮顯示)
GET xiaobai/user/_search
{
"query":{
"match":{
"name":"鑽石"
}
},
"highlight":{
"pre_tags": "<p class='key' style='color:red'>",
"post_tags": "</p>",
"fields": {
"name":{}
}
}
}
檢視執行結果:
#! [types removal] Specifying types in search requests is deprecated.
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.3250337,
"hits" : [
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "2",
"_score" : 1.3250337,
"_source" : {
"name" : "鑽石李老四",
"age" : "32",
"desc" : "社會性死亡",
"tags" : [
"技術宅",
"暖男",
"中年危機"
]
},
"highlight" : {
"name" : [
"<p class='key' style='color:red'>鑽</p><p class='key' style='color:red'>石</p>李老四"
]
}
},
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "3",
"_score" : 1.3250337,
"_source" : {
"name" : "鑽石王老五",
"age" : "19",
"desc" : "社會性死亡",
"tags" : [
"技術宅",
"暖男"
]
},
"highlight" : {
"name" : [
"<p class='key' style='color:red'>鑽</p><p class='key' style='color:red'>石</p>王老五"
]
}
}
]
}
}
參考Java REST Client官網文件:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/index.html
1、原生的依賴與初始化方法
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.12.1</version>
</dependency>
2、配置基本的專案:
(1)建立sprint-boot module
(2)module選擇elasticsearch
(3)檢視pom對應的依賴包
(4)調整匯入es版本依賴與已本地安裝的版本保持一致
pom -> spring-boot-starter-parent -> pring-boot-dependencies -> <elasticsearch.version>7.9.3</elasticsearch.version>
pom中調整為7.12.1,重新整理
<properties>
<java.version>1.8</java.version>
<spring-native.version>0.9.2</spring-native.version>
<!-- 自定義es版本依賴,保證與本地一致 -->
<elasticsearch.version>7.12.1</elasticsearch.version>
</properties>
檢視後修改成功
(5)構建RestHighLevelClient物件
package com.testbk.config;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
//找到RestHighLevelClient物件,注入spring中,分析一波原始碼
@Configuration //xml -bean
public class ElasticSearchClientConfig {
// spring < beans id="restHighLevelClient" class=RestHighLevelClient>
@Bean
public RestHighLevelClient restHighLevelClient(){
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("127.0.0.1",9200,"http")
)
);
return client;
}
}
3、索引API操作
(1)測試建立索引
//測試索引的建立 Request
@Test
void testCreatIndex() throws IOException {
//1、建立索引請求
CreateIndexRequest request = new CreateIndexRequest("mrwhite_index");
//2、客戶端建立請求,indicesClient,請求後獲取響應
CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT);
System.out.println(createIndexResponse);
}
檢視es外掛,索引建立成功
(2)測試獲取索引 -> 判斷索引是否存在
//測試獲取索引
@Test
void testExistIndex() throws IOException {
GetIndexRequest request = new GetIndexRequest("mrwhite_index");
boolean exists = client.indices().exists(request,RequestOptions.DEFAULT);
System.out.println(exists);
}
檢視執行結果:
true
(3)測試刪除索引
//測試刪除索引
@Test
void testDeleteIndex() throws IOException {
DeleteIndexRequest request = new DeleteIndexRequest("mrwhite_index");
AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT);
System.out.println(delete.isAcknowledged());
}
檢視執行結果:同時索引被刪除
true
4、文件API操作
(1)測試新增文件
建立使用者物件
package com.testbk.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Component
public class User {
private String name;
private int age;
}
建立索引並向索引內新增文件
//測試新增文件
@Test
void testAddDocument() throws IOException {
//建立物件
User user = new User("小白",30);
//建立請求
IndexRequest request = new IndexRequest("mrwhite_index");
//規則 PUT /mrwhite_index/_doc/1
request.id("1");
request.timeout(TimeValue.timeValueSeconds(1));
//將我們的資料放入請求json,新增fastjson依賴
request.source(JSON.toJSONString(user), XContentType.JSON);
//客戶端傳送請求
IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
System.out.println(indexResponse.toString());
System.out.println(indexResponse.status());
}
檢視執行結果:
IndexResponse[index=mrwhite_index,type=_doc,id=1,version=1,result=created,seqNo=0,primaryTerm=1,shards={"total":2,"successful":1,"failed":0}]
CREATED
(2)獲取文件,判斷是否存在
//獲取文件,判斷是否存在 get /index/doc/1
@Test
void testIsExists() throws IOException {
GetRequest getRequest = new GetRequest("mrwhite_index","1");
//不獲取返回的_source的上下文
getRequest.fetchSourceContext(new FetchSourceContext(false));
getRequest.storedFields("_none_");
boolean exists = client.exists(getRequest, RequestOptions.DEFAULT);
System.out.println(exists);
}
檢視執行結果:
true
(3)獲取文件的資訊
//獲取文件的資訊
@Test
void testGetDocument() throws IOException {
GetRequest getRequest = new GetRequest("mrwhite_index","1");
GetResponse documentFields = client.get(getRequest, RequestOptions.DEFAULT);
System.out.println(documentFields.getSourceAsString());//列印文件的內容
System.out.println(documentFields);
}
檢視執行結果:
{"age":30,"name":"小白"}
{"_index":"mrwhite_index","_type":"_doc","_id":"1","_version":1,"_seq_no":0,"_primary_term":1,"found":true,"_source":{"age":30,"name":"小白"}}
(4)更新文件的資訊
//更新文件的資訊
@Test
void testUpdateDocument() throws IOException {
UpdateRequest updateRequest = new UpdateRequest("mrwhite_index","1");
updateRequest.timeout("1s");
User user = new User("小白",32);
updateRequest.doc(JSON.toJSONString(user),XContentType.JSON);
UpdateResponse updateResponse = client.update(updateRequest, RequestOptions.DEFAULT);
System.out.println(updateResponse.status());
}
檢視執行結果:OK
(5)刪除文件的資訊
//刪除文件的資訊
@Test
void testDeleteDocument() throws IOException {
DeleteRequest request = new DeleteRequest("mrwhite_inex", "1");
request.timeout("1s");
DeleteResponse deleteResponse = client.delete(request, RequestOptions.DEFAULT);
System.out.println(deleteResponse.status());
}
檢視執行結果:OK,對應文件被刪除掉
(6)批量操作文件
//批量插入資料
@Test
void testBulkRequest() throws IOException {
BulkRequest bulkRequest = new BulkRequest();
bulkRequest.timeout("10s");
ArrayList<User> userList = new ArrayList<>();
userList.add(new User("xiaobai",15));
userList.add(new User("xiaobai",16));
userList.add(new User("xiaobai",17));
userList.add(new User("xiaobai",18));
userList.add(new User("xiaobai",19));
userList.add(new User("xiaobai",20));
userList.add(new User("xiaobai",21));
for (int i = 0; i <userList.size() ; i++) {
//id不用的話會隨機生成id
bulkRequest.add(new IndexRequest("mrwhite_index").id(""+(i+1)).source(JSON.toJSONString(userList.get(i)),XContentType.JSON));
}
BulkResponse bulkResponse=client.bulk(bulkRequest,RequestOptions.DEFAULT);
System.out.println(bulkResponse.hasFailures()); //列印是否失敗,fasle代表成功
}
返回false:
(7)查詢文件
//查詢文件
@Test
void testSearch() throws IOException {
SearchRequest searchRequest = new SearchRequest("mrwhite_index");
//構建搜尋條件
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//精確匹配
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name","xiaobai");
//匹配所有
//MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAll();
sourceBuilder.query(termQueryBuilder);
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
searchRequest.source(sourceBuilder);
SearchResponse searchResponse = client.search(searchRequest,RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(searchResponse.getHits()));
for(SearchHit documentFileds:searchResponse.getHits().getHits()){
System.out.println(documentFileds.getSourceAsMap());
}
}
檢視執行結果:
{"fragment":true,"hits":[{"fields":{},"fragment":false,"highlightFields":{},"id":"1","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":0.06453852,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"xiaobai","age":15},"sourceAsString":"{\"age\":15,\"name\":\"xiaobai\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"2","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":0.06453852,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"xiaobai","age":16},"sourceAsString":"{\"age\":16,\"name\":\"xiaobai\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"3","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":0.06453852,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"xiaobai","age":17},"sourceAsString":"{\"age\":17,\"name\":\"xiaobai\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"4","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":0.06453852,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"xiaobai","age":18},"sourceAsString":"{\"age\":18,\"name\":\"xiaobai\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"5","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":0.06453852,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"xiaobai","age":19},"sourceAsString":"{\"age\":19,\"name\":\"xiaobai\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"6","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":0.06453852,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"xiaobai","age":20},"sourceAsString":"{\"age\":20,\"name\":\"xiaobai\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"7","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":0.06453852,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"xiaobai","age":21},"sourceAsString":"{\"age\":21,\"name\":\"xiaobai\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1}],"maxScore":0.06453852,"totalHits":{"relation":"EQUAL_TO","value":7}}
{name=xiaobai, age=15}
{name=xiaobai, age=16}
{name=xiaobai, age=17}
{name=xiaobai, age=18}
{name=xiaobai, age=19}
{name=xiaobai, age=20}
{name=xiaobai, age=21}