目錄
一.下載鏡像文件
二.創(chuàng)建實(shí)例
2.1 創(chuàng)建elasticsearch實(shí)例
2.2 創(chuàng)建Kibana實(shí)例
三.es初步索引
1、_cat
2、索引一個(gè)文檔(保存)
3、查詢文檔
?4.更新文檔
5.刪除文檔&索引?
?6.bulk 批量 API
四.進(jìn)階檢索
1、SearchAPI
?2、Query DSL
1)、基本語(yǔ)法格式 Elasticsearch 提供了一個(gè)可以執(zhí)行查詢的 Json 風(fēng)格的 DSL(domain-specific language 領(lǐng)域特 定語(yǔ)言)。這個(gè)被稱為 Query DSL。該查詢語(yǔ)言非常全面,并且剛開始的時(shí)候感覺有點(diǎn)復(fù)雜, 真正學(xué)好它的方法是從一些基礎(chǔ)的示例開始的。
2)、match【匹配查詢】 (分詞)
3)、match_phrase【短語(yǔ)匹配】
4)、multi_match【多字段分詞匹配】
5)、bool【復(fù)合查詢】?
6)、filter【結(jié)果過(guò)濾?】
7)、term【精確匹配】
8)、aggregations(執(zhí)行聚合)?
?編輯?3、Mapping
1)、字段類型
?2)、映射
4.分詞?
測(cè)試分詞
1)、安裝 ik 分詞?
2)、測(cè)試分詞器
?編輯3)、自定義詞庫(kù)?
五、Elasticsearch-Rest-Client
1、SpringBoot 整合
1.導(dǎo)入依賴
2.新建配置類
3.測(cè)試
4.測(cè)試保存索引至es
??????????5.復(fù)雜檢索
一.下載鏡像文件
Docker安裝elasticsearch(存儲(chǔ)與檢索數(shù)據(jù))
[root@VM-12-8-centos ~]# docker pull elasticsearch:7.5.0
Docker安裝kibana(可視化檢索數(shù)據(jù))
[root@VM-12-8-centos ~]# docker pull kibana:7.5.0
查看下載的鏡像
[root@VM-12-8-centos ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
redis latest 7614ae9453d1 9 months ago 113MB
mysql 5.7 c20987f18b13 9 months ago 448MB
grafana/grafana latest 9b957e098315 9 months ago 275MB
kibana 7.5.0 a674d23325b0 4 years ago 388MB
elasticsearch 7.5.0 5acf0e8da90b 4 years ago 486MB
注意:elasticsearch與kibana版本要統(tǒng)一
二.創(chuàng)建實(shí)例
2.1 創(chuàng)建elasticsearch實(shí)例
2.1.1.提前創(chuàng)建好elasticsearch所需要掛載的data、config及插件的數(shù)據(jù)卷
[root@VM-12-8-centos ~]# mkdir -p /mydata/elasticsearch/config
[root@VM-12-8-centos ~]# mkdir -p /mydata/elasticsearch/data
[root@VM-12-8-centos ~]# mkdir -p /mydata/elasticsearch/plugins
2.1.2 配置允許所有ip可訪問(wèn)elasticsearch
[root@VM-12-8-centos ~]# echo "http.host: 0.0.0.0" >> /mydata/elasticsearch/config/elasticsearch.yml
2.1.3 保證權(quán)限
[root@VM-12-8-centos ~]# chmod -R 777 /mydata/elasticsearch/
2.1.4 啟動(dòng)elasticsearch
docker run --name elasticsearch -p 9200:9200 -p 9300:9300
-e "discovery.type=single-node"
-e ES_JAVA_OPTS="-Xms64m -Xmx512m"
-v /mydata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
-v /mydata/elasticsearch/data:/usr/share/elasticsearch/data
-v /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins
-d elasticsearch:7.5.0
其中:--name:指定實(shí)例名稱
? ? ? ? ? ?-p 9200:9200:將宿主機(jī)與容器端口映射,我們向es發(fā)送http請(qǐng)求或使用Rest Api與es通信將訪問(wèn)9200端口。
? ? ? ? ?? -p 9300:9300:在es集群節(jié)點(diǎn)中通訊端口默認(rèn)為9300
? ? ? ? ? ?-e "discovery.type=single-node":以單節(jié)點(diǎn)模式運(yùn)行
? ? ? ? ? ??-e ES_JAVA_OPTS="-Xms64m -Xmx512m":由于測(cè)試,設(shè)置初始占用內(nèi)存為64m,最大占用內(nèi)存為512
[root@VM-12-8-centos ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c8156b7a8987 elasticsearch:latest "/docker-entrypoint.…" 15 seconds ago Up 14 seconds 0.0.0.0:9200->9200/tcp, :::9200->9200/tcp, 0.0.0.0:9300->9300/tcp, :::9300->9300/tcp elasticsearch
注意:在防火墻打開對(duì)應(yīng)的端口!!
訪問(wèn)9200端口:
2.2 創(chuàng)建Kibana實(shí)例
2.2.1 創(chuàng)建kibana實(shí)例需要掛載的配置文件數(shù)據(jù)卷
[root@VM-12-8-centos ~]# mkdir /mydata/kibana/config
[root@VM-12-8-centos config]# touch kibana.yml
????????在kibana.yml中加入一下配置:
????????server.port: 9891? #修改端口
????????server.host: "0.0.0.0" # 修改任意主機(jī)訪問(wèn)
2.2.3 啟動(dòng)Kibana
[root@VM-12-8-centos config]# docker run --name kibana -e ELASTICSEARCH_HOSTS=http://xxx.xx.xx.x/:9200 -p 5601:5601 -v /mydata/kibana/config/kibana.yml:/usr/share/kibana/config/kibana.yml -d kibana:7.5.0
????????注意:-e ELASTICSEARCH_HOSTS 后面的參數(shù)為es容器內(nèi)部地址與端口!!
? ? ? ? 通過(guò)以下可查詢?nèi)萜鲀?nèi)容ip
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name_or_id
? ? ? ? 可通過(guò)一下查看容器日志(啟動(dòng)未成功,查看日志)
docker logs container_name_or_id
2.2.4 訪問(wèn)Kibana
? ? ? ? 我們通過(guò)服務(wù)器ip:5601訪問(wèn)kibana,看到以下則說(shuō)明kibana啟動(dòng)成功。
三.es初步索引
1、_cat
GET /_cat/nodes | 查看所有節(jié)點(diǎn) |
GET /_cat/health | 查看 es健康狀況 |
GET /_cat/master | 查看主節(jié)點(diǎn) |
GET /_cat/indices | 查看所有索引 相對(duì)于mysql中的show databases; |
2、索引一個(gè)文檔(保存)
保存一個(gè)數(shù)據(jù),保存在哪個(gè)索引的哪個(gè)類型下,指定用哪個(gè)唯一標(biāo)識(shí)
示例:PUT customer/external/1
在 customer 索引下的 external 類型下保存 1 號(hào)數(shù)據(jù)為
{ "name": "John Doe" }
?PUT 和 POST 操作都可以, POST 新增。如果不指定 id,會(huì)自動(dòng)生成 id。指定 id 就會(huì)修改這個(gè)數(shù)據(jù),并新增版本號(hào) PUT 可以新增可以修改。PUT 必須指定 id;由于 PUT 需要指定 id,我們一般都用來(lái)做修改 操作,不指定 id 會(huì)報(bào)錯(cuò)。
3、查詢文檔
1、GET customer/external/1
?結(jié)果:
{ "_index": "customer", //在哪個(gè)索引
"_type": "external", //在哪個(gè)類型
"_id": "1", //記錄 id
"_version": 2, //版本號(hào)
"_seq_no": 1, //并發(fā)控制字段,每次更新就會(huì)+1,用來(lái)做樂(lè)觀鎖
"_primary_term": 1, //同上,主分片重新分配,如重啟,就會(huì)變化
"found": true, "_source": { //真正的內(nèi)容
"name": "John Doe"
}
}
2、樂(lè)觀鎖的使用
請(qǐng)求參數(shù)后追加?if_seq_no=1&if_primary_term=1
源數(shù)據(jù)name為hello
A:修改name從 “hello” 到 ”A“
B:修改name從 “A” 到 ”B“
?4.更新文檔
POST customer/external/1/_update
post請(qǐng)求,且地址欄帶上_update 則指定這是個(gè)更新操作。
攜帶的json數(shù)據(jù)必須名為【doc】?
更新時(shí)會(huì)對(duì)比源文檔數(shù)據(jù),如果相同不會(huì)有什么操作,文檔 version 不增加
也可追加屬性
?post請(qǐng)求,且地址欄不帶上_update,json也不攜帶【doc】
?則直接更新文檔,文檔 version 增加
PUT??customer/external/1
與?POST customer/external/1 無(wú)異,即直接更新文檔,增加文檔version
5.刪除文檔&索引?
DELETE?customer/external/1? 刪除文檔
?DELETE?customer/? 刪除索引
?6.bulk 批量 API
POST customer/external/_bulk
語(yǔ)法格式:
{ action: { metadata }}? \n? ? ? ? ? ? ? ? ? ? ? ? ? ?可指定要操作的索引、類型、id
{ request body }? \n
{ action: { metadata }}? \n
{ request body }? \n
bulk API 以此按順序執(zhí)行所有的 action(動(dòng)作)。如果一個(gè)單個(gè)的動(dòng)作因任何原因而失敗, 它將繼續(xù)處理它后面剩余的動(dòng)作。當(dāng) bulk API 返回時(shí),它將提供每個(gè)動(dòng)作的狀態(tài)(與發(fā)送 的順序相同),所以您可以檢查是否一個(gè)指定的動(dòng)作是不是失敗了。
復(fù)雜實(shí)例:
POST /_bulk
四.進(jìn)階檢索
1、SearchAPI
ES 支持兩種基本方式檢索 :
???????? 一個(gè)是通過(guò)使用 REST request URI 發(fā)送搜索參數(shù)(uri+檢索參數(shù))
????????另一個(gè)是通過(guò)使用 REST request body 來(lái)發(fā)送它們(uri+請(qǐng)求體)
1)、檢索信息
一切檢索從_search 開始
GET bank/_search | 檢索 bank 下所有信息,包括 type 和 docs |
GET bank/_search?q=*&sort=account_number:asc | 請(qǐng)求參數(shù)方式檢索 |
?使用uri+檢索參數(shù):
響應(yīng)結(jié)果解釋:
took - Elasticsearch 執(zhí)行搜索的時(shí)間(毫秒)
time_out - 告訴我們搜索是否超時(shí)
_shards - 告訴我們多少個(gè)分片被搜索了,以及統(tǒng)計(jì)了成功/失敗的搜索分片
hits - 搜索結(jié)果
hits.total - 搜索結(jié)果
hits.hits - 實(shí)際的搜索結(jié)果數(shù)組(默認(rèn)為前 10 的文檔)
sort - 結(jié)果的排序 key(鍵)(沒有則按 score 排序)
score 和 max_score –相關(guān)性得分和最高得分(全文檢索用)
使用uri+請(qǐng)求體:
?2、Query DSL
1)、基本語(yǔ)法格式 Elasticsearch 提供了一個(gè)可以執(zhí)行查詢的 Json 風(fēng)格的 DSL(domain-specific language 領(lǐng)域特 定語(yǔ)言)。這個(gè)被稱為 Query DSL。該查詢語(yǔ)言非常全面,并且剛開始的時(shí)候感覺有點(diǎn)復(fù)雜, 真正學(xué)好它的方法是從一些基礎(chǔ)的示例開始的。
GET /bank/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"balance": {
"order": "desc"
}
}
],
"from": 10,
"size": 5,
"_source": ["account_number","balance"]
}
query 定義如何查詢。
match_all 查詢類型【代表查詢所有的所有】,es 中可以在 query 中組合非常多的查 詢類型完成復(fù)雜查詢。
除了 query 參數(shù)之外,我們也可以傳遞其它的參數(shù)以改變查詢結(jié)果。如 sort,size。
from+size限定,完成分頁(yè)功能。
sort 排序,多字段排序,會(huì)在前序字段相等時(shí)后續(xù)字段內(nèi)部排序,否則以前序?yàn)闇?zhǔn)。
_source返回部分字段
2)、match【匹配查詢】 (分詞)
1、匹配account_number為20的數(shù)據(jù)
GET /bank/_search
{
"query": {
"match": {
"account_number": 20
}
}
}
2、全文匹配 address 中帶有kings的數(shù)據(jù) (相當(dāng)與Mysql中的like查詢)?
GET /bank/_search
{
"query": {
"match": {
"address": "Kings"
}
}
}
?????????match匹配查詢會(huì)將關(guān)鍵字進(jìn)行分詞匹配,只要能匹配到的關(guān)鍵字都會(huì)被檢索出來(lái),最終以檢索的匹配度(即得分)進(jìn)行排序返回。
3)、match_phrase【短語(yǔ)匹配】
將需要匹配的值當(dāng)成一個(gè)整體單詞(不分詞)進(jìn)行檢索
?查出 address 中包含 Kings Place 的所有記錄,并給出相關(guān)性得分
4)、multi_match【多字段分詞匹配】
GET /bank/_search
{
"query": {
"multi_match": {
"query": "Kings Ribera",
"fields": ["city","address"]
}
}
}
即: 匹配address與city包含Kings或Ribera的數(shù)據(jù) (會(huì)進(jìn)行分詞匹配)
相當(dāng)于mysql中:where (address like %Kings%? or??address like %Ribera%)
????????????????????????????????????????????????????????????????????????or??
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (city like %Kings%? or??city like %Ribera%)
5)、bool【復(fù)合查詢】?
bool 用來(lái)做復(fù)合查詢: 復(fù)合語(yǔ)句可以合并 任何 其它查詢語(yǔ)句,包括復(fù)合語(yǔ)句,了解這一點(diǎn)是很重要的。這就意味 著,復(fù)合語(yǔ)句之間可以互相嵌套,可以表達(dá)非常復(fù)雜的邏輯
GET bank/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"gender":"M"
}
},
{
"match": {
"address": "mill"
}
}
],
"must_not": [
{
"match": {
"age":"20"
}
}
],
"should": [
{
"match": {
"firstname": "Forbes"
}
}
]
}
}
}
- must:必須達(dá)到 must 列舉的所有條件
- must_not : 必須不是指定的情況
- should:應(yīng)該達(dá)到 should 列舉的條件,如果達(dá)到會(huì)增加相關(guān)文檔的評(píng)分,并不會(huì)改變 查詢的結(jié)果。如果 query 中只有 should 且只有一種匹配規(guī)則,那么 should 的條件就會(huì) 被作為默認(rèn)匹配條件而去改變查詢結(jié)果
所以以上的查詢條件為:gender必須為M,address必須為mill,age不能為20,firstname應(yīng)該為Forbes。
6)、filter【結(jié)果過(guò)濾?】
? ? ? ? 假如我們想查詢年齡在18-30之間
1、在must使用range:
?會(huì)看到有貢獻(xiàn)相關(guān)性得分
2、使用filter過(guò)濾
會(huì)看到?filter并不會(huì)有相關(guān)性得分
7)、term【精確匹配】
和 match 一樣。匹配某個(gè)屬性的值。全文檢索字段用 match,其他非 text 字段匹配用 term。
8)、aggregations(執(zhí)行聚合)?
聚合提供了從數(shù)據(jù)中分組和提取數(shù)據(jù)的能力。最簡(jiǎn)單的聚合方法大致等于 SQL GROUP BY 和 SQL 聚合函數(shù)。在 Elasticsearch 中,您有執(zhí)行搜索返回 hits(命中結(jié)果),并且同時(shí)返 回聚合結(jié)果,把一個(gè)響應(yīng)中的所有 hits(命中結(jié)果)分隔開的能力。這是非常強(qiáng)大且有效的, 您可以執(zhí)行查詢和多個(gè)聚合,并且在一次使用中得到各自的(任何一個(gè)的)返回結(jié)果,使用 一次簡(jiǎn)潔和簡(jiǎn)化的 API 來(lái)避免網(wǎng)絡(luò)往返。
1、搜索 address 中包含 mill 的所有人的年齡分布以及平均年齡,但不顯示這些人的詳情:
????????????????size:0 則不返回命中結(jié)果?
2、按照年齡聚合,并且請(qǐng)求這些年齡段的這些人的平均薪資
3、查出所有年齡分布,并且這些年齡段中 M 的平均薪資和 F 的平均薪資以及這個(gè)年齡段的總體平均薪資?
?3、Mapping
1)、字段類型
?2)、映射
Mapping(映射) Mapping 是用來(lái)定義一個(gè)文檔(document),以及它所包含的屬性(field)是如何存儲(chǔ)和 索引的。比如,使用 mapping 來(lái)定義:
- 哪些字符串屬性應(yīng)該被看做全文本屬性(full text fields)。
- ?哪些屬性包含數(shù)字,日期或者地理位置。
- 文檔中的所有屬性是否都能被索引(_all 配置)。
- 日期的格式。
- 自定義映射規(guī)則來(lái)執(zhí)行動(dòng)態(tài)添加屬性。
- 查看 mapping 信息:
GET bank/_mapping
?在創(chuàng)建文檔時(shí),es會(huì)根據(jù)數(shù)據(jù)自動(dòng)猜測(cè)字段的數(shù)據(jù)類型。?
1、創(chuàng)建索引時(shí)指定映射
2、添加新的字段映射
?3、更新映射
對(duì)于已經(jīng)存在的映射字段,我們不能更新。更新必須創(chuàng)建新的索引進(jìn)行數(shù)據(jù)遷移
4、數(shù)據(jù)遷移
先創(chuàng)建出新索引的正確映射。然后使用如下方式進(jìn)行數(shù)據(jù)遷移?
POST _reindex [固定寫法]
{
? "source": {
? ? "index": "twitter"
? },
? "dest": {
? ? "index": "new_twitter"
? }
}
## 將舊索引的 type 下的數(shù)據(jù)進(jìn)行遷移
POST _reindex
{
? "source": {
? ? "index": "twitter",
? ? "type": "tweet"
? },
? "dest": {
? ? "index": "tweets"
? }
}
1、創(chuàng)建新索引并正確指定映射
?2、數(shù)據(jù)遷移
4.分詞?
一個(gè) tokenizer(分詞器)接收一個(gè)字符流,將之分割為獨(dú)立的 tokens(詞元,通常是獨(dú)立 的單詞),然后輸出 tokens 流。 例如,whitespace tokenizer 遇到空白字符時(shí)分割文本。它會(huì)將文本 "Quick brown fox!" 分割 為 [Quick, brown, fox!]。 該 tokenizer(分詞器)還負(fù)責(zé)記錄各個(gè) term(詞條)的順序或 position 位置(用于 phrase 短 語(yǔ)和 word proximity 詞近鄰查詢),以及 term(詞條)所代表的原始 word(單詞)的 start (起始)和 end(結(jié)束)的 character offsets(字符偏移量)(用于高亮顯示搜索的內(nèi)容)。 Elasticsearch 提供了很多內(nèi)置的分詞器,可以用來(lái)構(gòu)建 custom analyzers(自定義分詞器)。
測(cè)試分詞
默認(rèn)的標(biāo)準(zhǔn)分詞器為英文分詞,對(duì)于中文分詞不友好,會(huì)將中文的每個(gè)字作為一個(gè)詞元。?
1)、安裝 ik 分詞?
下載es對(duì)應(yīng)版本的ik分詞器
Release v7.5.0 · medcl/elasticsearch-analysis-ik · GitHub
進(jìn)入es容器掛載的plugins文件夾,將下載好的ik分詞器上傳到該文件夾
使用unset 解壓。
可以確認(rèn)是否安裝好了分詞器 進(jìn)入es容器內(nèi)部,cd ../bin elasticsearch plugin list:即可列出系統(tǒng)的分詞器
2)、測(cè)試分詞器
1、使用默認(rèn)的分詞器
2、使用ik_smart?
3、使用ik_max_word(最細(xì)粒度)
3)、自定義詞庫(kù)?
1.安裝nginx
- 隨便啟動(dòng)一個(gè) nginx 實(shí)例,只是為了復(fù)制出配置
docker run -p 80:80 --name nginx:1.10 # 沒有這個(gè)鏡像將會(huì)自動(dòng)下載鏡像
- 將容器內(nèi)的配置文件拷貝到當(dāng)前目錄:
- 將剛剛拿到的配置文件放到 mydata/ngxin/conf 中?
- 終止原容器:docker stop nginx
- 執(zhí)行命令刪除原容器:docker rm $ContainerId
- 創(chuàng)建新的 nginx;執(zhí)行以下命令
docker run -p 80:80 --name nginx -v /mydata/nginx/html:/usr/share/nginx/html -v /mydata/nginx/logs:/var/log/nginx -v /mydata/nginx/conf:/etc/nginx -d nginx:1.10
- 進(jìn)入mydata/ngxin/html中新建es文件夾,在es文件夾中新建一個(gè)fengci.txt,并用Vi命令在里面添加一些詞語(yǔ)。
2.修改/usr/share/elasticsearch/plugins/ik/config/中的 IKAnalyzer.cfg.xml
? ? ? ? 注意:這里的nginx地址要為nginx在容器中的地址:查詢?cè)谌萜髦械膇p
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name_or_id
?3.重啟es
4.測(cè)試
五、Elasticsearch-Rest-Client
1、SpringBoot 整合
1.導(dǎo)入依賴
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.5.0</version>
</dependency>
2.新建配置類
package com.xxx.gulimall.search.config;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Configuration;
@Configuration
public class GulimallElasticsearchConfig {
public RestHighLevelClient esRestClient(){
RestClientBuilder builder = null;
builder = RestClient.builder(new HttpHost("xxx.xxx.xx.xx",9200,"http"));
RestHighLevelClient client = new RestHighLevelClient(builder);
return client;
}
}
?3.測(cè)試
?4.測(cè)試保存索引至es
1.設(shè)置請(qǐng)求設(shè)置項(xiàng)
import org.apache.http.HttpHost;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class GulimallElasticsearchConfig {
// 設(shè)置請(qǐng)求設(shè)置項(xiàng)
public static final RequestOptions COMMON_OPTIONS;
static {
RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();
// builder.addHeader("Authorization", "Bearer " + TOKEN);
// builder.setHttpAsyncResponseConsumerFactory(
// new HttpAsyncResponseConsumerFactory
// .HeapBufferedResponseConsumerFactory(30 * 1024 * 1024 * 1024));
COMMON_OPTIONS = builder.build();
}
@Bean
public RestHighLevelClient esRestClient(){
RestClientBuilder builder = null;
builder = RestClient.builder(new HttpHost("xxx.xxx.xx.xx",9200,"http"));
RestHighLevelClient client = new RestHighLevelClient(builder);
return client;
}
}
2.測(cè)試代碼
package com.liucan.gulimall.search;
import com.alibaba.fastjson.JSON;
import com.liucan.gulimall.search.config.GulimallElasticsearchConfig;
import lombok.Data;
import org.apache.catalina.User;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.io.IOException;
@SpringBootTest
class GulimallSearchApplicationTests {
@Autowired
private RestHighLevelClient client;
@Test
void indexData() throws IOException {
IndexRequest indexRequest = new IndexRequest("users");
indexRequest.id("1"); //數(shù)據(jù)的id
// indexRequest.source("userName","zhangsan","age",18,"gender","男");
User user = new User();
user.setUserName("zhangsan");
user.setAge(18);
user.setGender("男");
String jsonString = JSON.toJSONString(user);
indexRequest.source(jsonString, XContentType.JSON); //要保存的內(nèi)容
//執(zhí)行操作
IndexResponse index = client.index(indexRequest, GulimallElasticsearchConfig.COMMON_OPTIONS);
//提取有用的響應(yīng)數(shù)據(jù)
System.out.println(index);
}
@Data
class User{
private String userName;
private String gender;
private Integer age;
}
@Test
void contextLoads() {
System.out.println("========================================"+client);
}
}
響應(yīng):
在kibana中查看:
?5.復(fù)雜檢索
/**
* 復(fù)雜檢索
* @throws IOException
*/
@Test
void searchData() throws IOException {
// 1、創(chuàng)建檢索請(qǐng)求
SearchRequest request = new SearchRequest();
// 指定索引
request.indices("bank");
// 指定DSL 檢索條件
SearchSourceBuilder builder = new SearchSourceBuilder();
// 1.1 構(gòu)造檢索條件
builder.query(QueryBuilders.matchQuery("address","mill"));
// 1.2按照年齡值分布進(jìn)行聚合
TermsAggregationBuilder ageAgg = AggregationBuilders.terms("ageAgg").field("age").size(10);
builder.aggregation(ageAgg);
// 1.3 balance平均值
AvgAggregationBuilder balanceAvg = AggregationBuilders.avg("balanceAvg").field("balance");
builder.aggregation(balanceAvg);
request.source(builder);
// 2、執(zhí)行檢索請(qǐng)求
SearchResponse search = client.search(request, GulimallElasticsearchConfig.COMMON_OPTIONS);
// 3、分析結(jié)果 search
System.out.println(search);
// 3.1 獲取查詢到的數(shù)據(jù)
SearchHits hits = search.getHits();
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
String sourceAsString = hit.getSourceAsString();
Account account = JSON.parseObject(sourceAsString, Account.class);
System.out.println(account);
}
// 獲取檢索到的聚合信息
Aggregations aggregations = search.getAggregations();
Terms ageAgg1 = aggregations.get("ageAgg");
for (Terms.Bucket bucket : ageAgg1.getBuckets()) {
String keyAsString = bucket.getKeyAsString();
System.out.println("年齡:"+keyAsString+"=====>"+bucket.getDocCount());
}
Avg balanceAvg1 = aggregations.get("balanceAvg");
double value = balanceAvg1.getValue();
System.out.println("balance平均值:"+value);
}
結(jié)果:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-761646.html
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-761646.html
六. 關(guān)于 nested 類型
- Object 數(shù)據(jù)類型的數(shù)組會(huì)被扁平化處理為一個(gè)簡(jiǎn)單的鍵與值的列表,即對(duì)象的相同屬性會(huì)放到同一個(gè)數(shù)組中,在檢索時(shí)會(huì)出現(xiàn)錯(cuò)誤。參考官網(wǎng):How arrays of objects are flattened
- 對(duì)于 Object 類型的數(shù)組,要使用 nested 字段類型。參考官網(wǎng):Using nested fields for arrays of objects
到了這里,關(guān)于Elasticsearch基礎(chǔ)入門及整合SpringBoot的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!