ElasticSearch 入門
本篇為 ElasticSearch 入門學(xué)習(xí)總結(jié)筆記,課程視頻地址:ElasticSearch 入門
一、ElasticSearch 簡介
1.1彤灶、什么是ElasticSearch
? 簡稱 ES
- 基于Apache Lucene 構(gòu)建的 開源搜索引擎康吵,提供一個分布式多用戶能力的全文搜索引擎
- 采用 JAVA 編寫的 福稳,提供簡單易用的 RESTFul API(RESTFul web接口),當前流行的企業(yè)級搜索引擎
- 輕松的 橫向擴展途茫,可支持PB級 的結(jié)構(gòu)化或非結(jié)構(gòu)化數(shù)據(jù)處理
- 可以準實時地快速存儲碟嘴、搜索溪食、分析海量的數(shù)據(jù)逸嘀。(用于云計算中谱邪,能夠達到實時搜索)
1.2、應(yīng)用場景
- 海量數(shù)據(jù)分析引擎(聚合搜索)
- 站內(nèi)搜索引擎
- 數(shù)據(jù)倉庫
1.3、誰在用ES呢?
英國衛(wèi)報— 實時分析公眾對文章的回應(yīng)
維基百科荔烧、GitHub - 站內(nèi)實時搜索
百度—實時日志監(jiān)控平臺
阿里、Google抵乓、小米店归、京東....
1.4、環(huán)境要求
工具 | 版本 |
---|---|
IDE | IDEA或Eclipse |
JAVA | JDK8 |
Maven | 3.x 以上 |
NodeJS | 6.0以上 |
二醒叁、ElasticSearch 安裝
2.1司浪、ES版本問題
- 版本歷史 : 1.x-》2.x-》5.x -》最新6.0
- 版本選擇 : 選擇6.0進行演練!
2.2把沼、ES安裝-單實例
下載地址:ES Downloads啊易,windows環(huán)境下載 ZIP sha
,Linux或者Mac環(huán)境下饮睬,下載TAR sha
租谈。
windows 下安裝elasticsearch(有訪問頁面)
ElasticSearch安裝部署(Windows)(添加到windows)
2.2.1 單實例的安裝(Windows)
1、下載ES zip包
2捆愁、安裝Jdk8,并查看環(huán)境變量配置
3割去、解壓ES包
- 目錄說明:
目錄名 | 說明 |
---|---|
config | 配置文件 |
modules | 模塊存放目錄 |
bin | 腳本 |
lib | 第三方庫 |
plugins | 第三方插件 |
4、啟動驗證服務(wù)
? windows環(huán)境在/bin 下載雙擊 elasticsearch.bat
昼丑。啟動成功呻逆,看到starting....最后是started!
[2018-08-18T22:18:41,578][INFO ][o.e.n.Node ] [-Jy0w6-] starting ...
[2018-08-18T22:18:44,044][INFO ][o.e.t.TransportService ] [-Jy0w6-] publish_address {127.0.0.1:9300}, bound_addresses {127.0.0.1:9300}, {[::1]:9300}
{ml.machine_memory=8441524224, xpack.installed=true, ml.max_open_jobs=20, ml.enabled=true}, reason: apply cluster state (from master [master {-Jy0w6-}{-Jy0w6-QTKquaudbtTAQMQ}
[2018-08-18T22:18:48,923][INFO ][o.e.x.s.t.n.SecurityNetty4HttpServerTransport] [-Jy0w6-] publish_address {127.0.0.1:9200}, bound_addresses {127.0.0.1:9200}, {[::1]:9200}
[2018-08-18T22:18:48,924][INFO ][o.e.n.Node ] [-Jy0w6-] started
? 然后訪問 http://localhost:9200/ ,頁面響應(yīng)json格式數(shù)據(jù)菩帝,服務(wù)啟動正常页慷!
2.2.2 實用插件Head安裝(Windows)
ES 默認返回的信息在頁面上是Json格式顯示!不太友好!
Head插件的優(yōu)點:
- 提供了友好的web界面胁附,解決數(shù)據(jù)在界面顯示問題
- 實現(xiàn)基本信息的查看和Restful 請求的模擬以及數(shù)據(jù)的基本檢索
1酒繁、安裝Head的步驟
? 1)、安裝Node 6.x以上J環(huán)境控妻,安裝 執(zhí)行指令npm install -g grunt -cli
進行安裝grunt州袒。
? 2)、 下載elasticsearch-head包弓候,在Github【elasticsearch-head】上面,直接選擇下載的DownLoad zip到本地郎哭!
? 3)他匪、保存在 F:\elasticsearch_learn\ 文件夾下面并對 elasticsearch-head 進行解壓!
? 4)夸研、在 F:\elasticsearch_learn\elasticsearch-head-master文件夾目錄下面邦蜜,使用 npm install
!
F:\elasticsearch_learn\elasticsearch-head-master>npm install
注意:第一次==執(zhí)行失敗了!==報了下面的錯誤(可能是網(wǎng)絡(luò)不好的原因亥至,網(wǎng)絡(luò)好的時候在嘗試執(zhí)行一次)悼沈,但是服務(wù)啟動沒有問題!
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.0.0
npm ERR! node v6.10.3
npm ERR! npm v3.10.10
npm ERR! code ELIFECYCLE
npm ERR! phantomjs-prebuilt@2.1.16 install: `node install.js`
npm ERR! Exit status 1
....
npm ERR! Please include the following file with any support request:
npm ERR! F:\elasticsearch_learn\elasticsearch-head-master\npm-debug.log
? 5)姐扮、doc窗口 在 F:\elasticsearch_learn\elasticsearch-head-master文件夾目錄下面執(zhí)行
# npm run start 或者 grunt server
F:\elasticsearch_learn\elasticsearch-head-master>npm run start
? 6)絮供、驗證服務(wù),默認訪問地址http://localhost:9100茶敏,如下圖顯示:
2壤靶、修改相應(yīng)的配置
ElasticSearch和 elasticsearch-head 本質(zhì)上是兩個服務(wù)進程,訪問存在跨域問題惊搏,需要進行一些設(shè)置贮乳。
在 elasticsearch安裝目錄 /config/elasticsearch.yml
,在這個配置文件的末尾追加下面兩行配置信息并保存!
http.cors.enabled: true
http.cors.allow-origin: "*"
屬性 | 缺省值 | 描述 |
---|---|---|
http.cors.enabled | true | 如果啟用了 HTTP 端口恬惯,那么此屬性會指定是否允許跨源 REST 請求向拆。 |
http.cors.allowed.origin | localhost | 如果 http.cors.enabled 的值為 true,那么該屬性會指定允許 REST 請求來自何處宿崭。 |
更多屬性配置亲铡,請查看 【Elasticsearch 服務(wù)配置屬性】
3、驗證elasticsearch和 elasticsearch-head
- 啟動 elasticsearch服務(wù)
- 啟動elasticsearch-head 服務(wù)
訪問 http://localhost:9100 地址葡兑!查看elasticsearch 集群健康值是否正常奖蔓!正常如下圖:
==注: 集群健康值==
red(差):集群 健康狀況很差,雖然可以查詢讹堤,但是已經(jīng)出現(xiàn)了丟失數(shù)據(jù)的現(xiàn)象 吆鹤;
yellow(中):集群健康狀況不是很好,但是集群可以正常使用 洲守;
green(優(yōu)):集群健康狀況良好疑务,集群正常使用。
2.3梗醇、ES安裝-分布式安裝
1)知允、安裝說明,安裝三個節(jié)點叙谨,一個master 温鸽,兩個slave。
集群名稱 | ip-端口 |
---|---|
myEsCluster (master) | 127.0.0.1:9500 |
myEsCluster(slave) | 127.0.0.1:9600 |
myEsCluster(slave) | 127.0.0.1:9700 |
2)、Es安裝包解壓出三份ES涤垫,修改每個 elasticsearch安裝目錄 /config/elasticsearch.yml
這個配置文件
master配置說明:
# 設(shè)置支持elasticsearch-head
http.cors.enabled: true
http.cors.allow-origin: "*"
# 設(shè)置集群master配置信息
# 首先要指定 集群的名字 ,名字隨便起姑尺,符合常規(guī)命名規(guī)則
cluster.name: myEsCluster
# 節(jié)點的名字,一般為master 或者 slave
node.name: master
# 節(jié)點是否為master蝠猬,設(shè)置為true的話切蟋,說明此節(jié)點為master節(jié)點
node.master: true
# 設(shè)置網(wǎng)絡(luò),如果是本機的話就是127.0.0.1,其他服務(wù)器配置對應(yīng)的IP地址即可
network.host: 127.0.0.1
# 默認端口為 9200,可以修改默認設(shè)置
http.port: 9500
slave配置說明:
# 設(shè)置集群slave配置信息
# 首先要指定 集群的名字 ,名字隨便起榆芦,符合常規(guī)命名規(guī)則
cluster.name: myEsCluster
# 節(jié)點的名字柄粹,一般為master 或者 slave
node.name: slave1
# 節(jié)點是否為master,設(shè)置為true的話歧杏,說明此節(jié)點為master節(jié)點
node.master: false
# 默認端口為 9200,可以修改默認設(shè)置
http.port: 9600
# 設(shè)置網(wǎng)絡(luò),如果是本機的話就是127.0.0.1镰惦,其他服務(wù)器配置對應(yīng)的IP地址即可
network.host: 127.0.0.1
# 設(shè)置集群中master節(jié)點的初始列表迷守,可以通過這些節(jié)點來自動發(fā)現(xiàn)新加入集群的節(jié)點犬绒。可以是一個數(shù)組兑凿。
# #discovery.zen.ping.unicast.hosts: ["host1", "host2"]
discovery.zen.ping.unicast.hosts: ["127.0.0.1"]
==兩個slave配置只需要改相應(yīng)的端口號即可凯力!一個slave1:9600 ,一個slave2:9700礼华。==
更多配置參考:
3)咐鹤、配置后完成后,啟動master的圣絮,然后啟動Slave祈惶,也啟動elasticsearch-head服務(wù),此時頁面可以查看Es集群的狀態(tài)扮匠!如下圖所示:
2.4捧请、 總結(jié)
從上面的安裝來看,Es的安裝相對還是比較簡單棒搜,并且在安裝分布式的時候疹蛉,通過簡單的配置就可以快速擴展多個ES節(jié)點,能夠快速的進行擴容力麸,非常靈活可款,方便!
三克蚂、ElasticSearch 基礎(chǔ)概念
3.1闺鲸、基本概念
集群和節(jié)點
集群:是由一個或者多個ES節(jié)點組成的集合。 每一個集群都有一個唯一的名字埃叭,默認是ElasticSearch摸恍。每個節(jié)點也都有唯一名字。
索引
索引: 含有相同屬性的文檔集合游盲,比如產(chǎn)品的索引误墓,用戶的索引等
類型:索引可以定義一個或多個類型蛮粮,文檔必須屬于一個類型(一般會定義有相同字段的文檔為一個類型)
文檔:文檔是可以被所有的基本數(shù)據(jù)單位,是整個ES中最小的存儲單位
==索引在Es中是通過一個名字來識別的谜慌,而且它的名字必須是 英文字母小寫然想,且不能有中劃線。==
都是通過這個名字來進行增刪查改欣范。
ES | 數(shù)據(jù)庫 |
---|---|
索引 | 實例database |
類型 | 表-table |
文檔 | 一行記錄 |
舉例:圖書索引 ---> 文學(xué)類型变泄、技能類型...---->每一本書可以看成一個文檔
分片和備份
分片: 每個索引都有多個分片,每個分片是一個Lucene索引
? 分片的好處:假如數(shù)據(jù)量很大的話恼琼,就會造成硬盤的壓力很大妨蛹,同時搜索速度也會出現(xiàn)瓶頸,將索引分成多個分片晴竞,從而分攤壓力提供效率蛙卤。
備份:拷貝一份分片就完成了分片的備份,提供可用性
ES默認在創(chuàng)建索引的時候噩死,會創(chuàng)建5個分片颤难,1個備份。這個默認的數(shù)量是可以修改的已维。
? number_of_shards: 每個索引的主分片數(shù)行嗤,默認值是 5 。這個配置在索引創(chuàng)建后不能修改垛耳。
? number_of_replicas:每個主分片的副本數(shù)栅屏,默認值是 1 。對于活動的索引庫堂鲜,這個配置可以隨時修改栈雳。
==注意==:索引的分片只能在創(chuàng)建索引的時候指定,而不能再后期進行修改泡嘴。備份是可以動態(tài)修改的甫恩。
四、ElasticSearch 基本用法
ES是以Restful API的風(fēng)格來命名的酌予。
-
API 的基本格式
http://<ip>:<port>/<索引>/<類型>/<文檔id>
-
常用HTTP動詞
GET/PUT/POST/DELETE
4.1磺箕、索引的創(chuàng)建
問題:如何確定一個索引是非結(jié)構(gòu)化還是結(jié)構(gòu)的化的呢?
結(jié)合Head插件抛虫,索引-->索引信息松靡,查看JSON數(shù)據(jù)中mappings建椰,如果數(shù)據(jù)為空,則說明是非結(jié)構(gòu)化索引屠列。
非結(jié)構(gòu)化創(chuàng)建
使用Head插件進行索引的創(chuàng)建,在tab標簽上夏志,選擇索引
,點 新建索引
苛让,輸入索引的名稱沟蔑,注意名稱的命名規(guī)則。(我自己驗證狱杰,中文瘦材、有中劃線的索引名字都可以創(chuàng)建成功!但是字母必須是小寫7禄)
創(chuàng)建成功每個框框食棕,都是Es索引的分片,粗線框是主分片 和 細線框 是分片的備份颁湖。
結(jié)構(gòu)化創(chuàng)建
1)宣蠕、使用Head插件進行索引的創(chuàng)建例隆,在tab標簽上甥捺,選擇復(fù)合查詢
,進行如下配置:
2)镀层、或者使用PostMan工具進行索引的創(chuàng)建
說明:
在Elasticsearch 6.0.0或更高版本中創(chuàng)建的索引只包含一個mapping type镰禾。 在5.x中使用multiple mapping types創(chuàng)建的索引將繼續(xù)像以前一樣在Elasticsearch 6.x中運行。 Mapping types將在Elasticsearch 7.0.0中完全刪除唱逢。
Indices created in Elasticsearch 6.0.0 or later may only contain a single mapping type. Indices created in 5.x with multiple mapping types will continue to function as before in Elasticsearch 6.x. Mapping types will be completely removed in Elasticsearch 7.0.0.
PUT 127.0.0.1:9500/people
請求參數(shù):
{
"settings":{
"number_of_shards":3,
"number_of_replicas":1
},
"mappings":{
"man":{
"properties":{
"name":{
"type":"text"
},
"age":{
"type":"integer"
},
"birth":{
"type":"date",
"format":"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
},
"country":{
"type":"keyword"
}
}
},
"woman":{}
}
}
結(jié)果:
{
"acknowledged": true,
"shards_acknowledged": true,
"index": "people"
}
如果一個mappings中有兩個type的話吴侦,在提交的時候會報如下錯誤:
PUT 127.0.0.1:9500/people2
參數(shù):
{
"settings":{
"number_of_shards":3,
"number_of_replicas":1
},
"mappings":{
"man":{
"properties":{
"name":{
"type":"text"
},
"age":{
"type":"integer"
},
"birth":{
"type":"date",
"format":"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
},
"country":{
"type":"keyword"
}
}
},
"woman":{}
}
}
結(jié)果:
{
"error": {
"root_cause": [
{
"type": "illegal_argument_exception",
"reason": "Rejecting mapping update to [people2] as the final mapping would have more than 1 type: [woman, man]"
}
],
"type": "illegal_argument_exception",
"reason": "Rejecting mapping update to [people2] as the final mapping would have more than 1 type: [woman, man]"
},
"status": 400
}
4.2、插入
文檔ID是一個唯一索引值坞古,指向我們的文檔數(shù)據(jù)织堂。
指定文檔ID插入
PUT 127.0.0.1:9500/people/man/1
指定插入文檔的ID為 1.
參數(shù):
{
"name":"dufy",
"age":27,
"birth":"1992-09-28",
"country":"China"
}
請求結(jié)果:
{
"_index": "people",
"_type": "man",
"_id": "1", # id 為1
"_version": 1,
"result": "created", # 標識創(chuàng)建一個文檔
"_shards": {
"total": 2,
"successful": 2,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1
}
使用Head插件查看數(shù)據(jù):
自動產(chǎn)生文檔ID插入
自動產(chǎn)生ID和上面指定ID插入不同的兩個地方是:
(1)易阳、在請求地址上不需要指定 ID,讓ES自動幫我們創(chuàng)建ID!
(2)潦俺、請求方式為POST方式
POST 127.0.0.1:9500/people/man
請求參數(shù):
{
"name":"dufy_auto_id",
"age":37,
"birth":"1982-09-28",
"country":"China"
}
請求結(jié)果:
{
"_index": "people",
"_type": "man",
"_id": "zmLSUGUBWifqa4luPRp5", # 自動創(chuàng)建ID
"_version": 1,
"result": "created", # 標識創(chuàng)建一個文檔
"_shards": {
"total": 2,
"successful": 2,
"failed": 0
},
"_seq_no": 1,
"_primary_term": 1
}
使用Head插件查看數(shù)據(jù):
4.3 、修改
直接修改文檔
POST 127.0.0.1:9500/people/man/1/_update
注意:需要在請求的地址后面加上 _update
,標識是一個修改操作肖爵。
請求參數(shù):
{
"doc":{
"name":"dufy_update"
}
}
請求響應(yīng)結(jié)果:
{
"_index": "people",
"_type": "man",
"_id": "1", # 標識文檔的ID為1
"_version": 2,
"result": "updated", # 標識修改一個文檔
"_shards": {
"total": 2,
"successful": 2,
"failed": 0
},
"_seq_no": 2,
"_primary_term": 1
}
通過Head插件查看法挨,發(fā)現(xiàn)文檔ID為1 name已經(jīng)修改了。
腳本修改文檔
腳本修改和直接修改的API是一樣的荐糜,只是參數(shù)有些區(qū)別。
POST 127.0.0.1:9500/people/man/1/_update
第一種方式請求參數(shù):
{
"script":{
"lang":"painless" , # ES 腳本語言
"inline":"ctx._source.age += 10" #ctx:es上下文绣张,_source:代表es當前的文檔沼撕,age:字段
}
}
第二種方式請求參數(shù):
{
"script":{
"lang":"painless" ,
"inline":"ctx._source.age = params.age",
"params":{ #使用params 指定數(shù)據(jù)值
"age":80
}
}
}
4.4、刪除
刪除文檔
DELETE 127.0.0.1:9500/people/man/1
使用delete請求笼沥,通過文檔的ID進行刪除操作。
{
"_index": "people",
"_type": "man",
"_id": "1",
"_version": 5,
"result": "deleted", # 標識刪除一個文檔
"_shards": {
"total": 2,
"successful": 2,
"failed": 0
},
"_seq_no": 5,
"_primary_term": 1
}
刪除索引
刪除操作是一個比較危險的操作乘凸,因為索引一旦刪除营勤,對應(yīng)的所有數(shù)據(jù)全部被刪除了寿羞。
可以通過Head插件刪除绪穆。確認輸入
刪除
,索引就刪除了难菌。-
使用 PostMan進行刪除,使用 請求燎窘,只輸入請求的索引
127.0.0.1:9500/people
4.5褐健、查詢-重點
查詢功能是使用過操作比較頻繁的。
首先進行數(shù)據(jù)初始化,創(chuàng)建一個book 的索引务蝠,然后插入一些數(shù)據(jù)馏段。具體的創(chuàng)建索引和插入數(shù)據(jù),查看之前內(nèi)容喷舀。
PUT 127.0.0.1:9500/book
結(jié)構(gòu)化創(chuàng)建:
{
"mappings":{
"novel":{
"properties":{
"author":{
"type":"text"
},
"word_count":{
"type":"integer"
},
"publish_date":{
"type":"date",
"format":"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
},
"title":{
"type":"keyword"
}
}
}
}
}
插入文檔數(shù)據(jù):
POST 127.0.0.1:9500/book/novel/1
{
"title":"Nginx",
"word_count":5000,
"publish_date":"2992-09-28",
"author":"zhangyc"
}
簡單查詢
GET 127.0.0.1:9500/book/novel/4
{
"_index": "book",
"_type": "novel",
"_id": "4",
"_version": 1,
"found": true,
"_source": { # 查詢出來索引為book,類型是novel的ID=4 的文檔數(shù)據(jù)
"title": "Dubbo",
"word_count": 8000,
"publish_date": "1992-09-28",
"author": "alibb"
}
}
條件查詢
POST 127.0.0.1:9500/book/_search
- 查詢?nèi)繑?shù)據(jù)
{
"query":{ # 查詢是以query為關(guān)鍵詞的
"match_all":{} # 查詢?nèi)康臄?shù)據(jù)
}
}
返回結(jié)果:
{
"took": 8, # 接口響應(yīng)花費的時間/ms
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 5, # 總共數(shù)據(jù)5條
"max_score": 1,
"hits": [ # 擊中,也就是響應(yīng)的全部數(shù)據(jù)券敌,hits默認返回的數(shù)據(jù)為10條,可以修改咱士!
{
"_index": "book",
"_type": "novel",
"_id": "5",
"_score": 1,
"_source": {
"title": "Nginx",
"word_count": 5000,
"publish_date": "2992-09-28",
"author": "zhangyc"
}
},
{....} #其他的數(shù)據(jù)信息
}
]
}
}
修改 hits默認返回數(shù)據(jù)的總數(shù)。
{
"query":{ # 查詢是以query為關(guān)鍵詞的
"match_all":{} # 查詢?nèi)康臄?shù)據(jù)
},
"size":2 # 返回數(shù)據(jù)的總數(shù)
}
-
關(guān)鍵詞查詢
POST 127.0.0.1:9500/book/_search
{
"query":{
"match":{
"title": "Redis實戰(zhàn)"
},
# 默認 排序 使用 _score
"sort":[ # 如何查詢數(shù)據(jù)較多,可以進行排序操作
{"publish_date":{"order":"desc"}}
]
}
}
{
"took": 7,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.2876821,
"hits": [
{
"_index": "book",
"_type": "novel",
"_id": "3",
"_score": 0.2876821,
"_source": {
"title": "Redis實戰(zhàn)",
"word_count": 2000,
"publish_date": "1582-09-28",
"author": "marry"
}
}
]
}
}
聚合查詢
POST 127.0.0.1:9500/book/_search
- 對書籍的字數(shù)進行聚合
查詢參數(shù):
{
"aggs":{
"groud_word_count":{ # 自定義聚合名稱
"terms":{
"field":"word_count"
}
}
}
}
返回結(jié)果:
{
# 其他數(shù)據(jù)省略
"aggregations": {
"groud_word_count": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": 5000,
"doc_count": 2 # 文檔總數(shù)
},
{
"key": 2000,
"doc_count": 1
},
{
"key": 8000,
"doc_count": 1
},
{
"key": 10000,
"doc_count": 1
}
]
}
}
}
上面這個是單個聚合,多個聚合同理:
{
"aggs":{
"groud_word_count":{ # 自定義聚合名稱
"terms":{
"field":"word_count"
}
},
"groud_title":{ # 自定義聚合名稱
"terms":{
"field":"title"
}
}
}
}
- 進行函數(shù)計算
{
"aggs":{
"grades_word_count":{
"stats":{ #統(tǒng)計數(shù)據(jù) min 、max顽耳、avg射富、avg
"field":"word_count"
}
}
}
}
返回結(jié)果:
"aggregations": { # 聚合
"grades_word_count": {
"count": 5,
"min": 2000,
"max": 10000,
"avg": 6000,
"sum": 30000
}
}
五、ElasticSearch 高級查詢
子條件查詢
特定字段查詢 所指特定值
1柴灯、Query Context
在查詢過程中,除了判斷文檔是否滿足查詢條件外弛槐,ES還會計算一個_score來標識匹配的程度店枣,旨在判斷目標文檔和查詢條件匹配的有多好(匹配度)!
- 全文本查詢 —— 針對文本類型數(shù)據(jù)
- 字段級別查詢——針對結(jié)構(gòu)化數(shù)據(jù)钧唐,如數(shù)字、日期等
{
"query":{
"multi_match":{ # 多條件查詢
"query":"Redis",
"fields":["title","author"]
}
}
}
語法查詢:
{
"query":{
"query_string":{
"query":"入門 OR Redis",
"fields":["title","author"]
}
}
}
字段級別的查詢:
{
"query":{
"term":{
"word_count":5000
}
}
}
字數(shù)或者日期范圍:
{
"query":{
"range":{
"word_count":{
"gte":1000,
"lte":5000
}
}
}
}
2匠襟、Filter Context
{
"query":{
"bool":{
"filter":{
"term":{
"word_count":5000
}
}
}
}
}
復(fù)合條件查詢
以一定的邏輯組合子條件查詢,結(jié)合了Query和Filter Context
固定分數(shù)查詢
布爾查詢
六钝侠、ElasticSearch 實戰(zhàn)演練
1、配置Spring boot ElasticSearch開發(fā)環(huán)境
1酸舍、創(chuàng)建Spring boot web項目帅韧,spring boot 使用2.0.4版本, elasticsearch為5.6.10
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<!--引入ELasticSearch的依賴包,默認使用elasticsearch5.6.10版本-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<!--需要引入transport-netty3-client忽舟,否則會啟動報錯-->
<dependency>
<groupId>org.elasticsearch.plugin</groupId>
<artifactId>transport-netty3-client</artifactId>
<version>5.6.10</version>
</dependency>
2、配置代碼
/**
* ES 配置類
* @author:dufyun
* @version:1.0.0
* @date 2018/8/19
* @update:[日期YYYY-MM-DD] [更改人姓名][變更描述]
*/
@Configuration
public class ElasticSearchConfig {
private static final Logger logger = LoggerFactory.getLogger(ElasticSearchConfig.class);
@Bean
public TransportClient transportClient() {
logger.info("初始化開始竞阐。丢氢。。狈茉。仁讨。");
TransportClient client = null;
try {
TransportAddress transportAddress = new InetSocketTransportAddress(InetAddress.getByName("localhost"),
Integer.valueOf(9300));
// 配置信息
Settings esSetting = Settings.builder()
.put("cluster.name","myEsCluster")
.build();
//配置信息Settings自定義,下面設(shè)置為EMPTY
client = new PreBuiltTransportClient(esSetting);
client.addTransportAddresses(transportAddress);
} catch (Exception e) {
logger.error("elasticsearch TransportClient create error!!!", e);
}
return client;
}
}
也可以使用配置文件锐墙!
es.hostName=localhost
es.transport=9300
es.cluster.name=myEsCluster
@Configuration
@PropertySource(value={"classpath:elasticsearch.properties"}) // 加載 指定的配置,只支持properti
public class ElasticSearchConfig {
private static final Logger logger = LoggerFactory.getLogger(ElasticSearchConfig.class);
@Value("${es.hostName}")
private String hostName;
@Value("${es.transport}")
private Integer transport;
@Value("${es.cluster.name}")
private String clusterName;
@Bean
public TransportClient transportClient() {
LOGGER.info("初始化開始。。际跪。。慨代。");
TransportClient client = null;
try {
TransportAddress transportAddress = new InetSocketTransportAddress(InetAddress.getByName(hostName),
Integer.valueOf(transport));
// 配置信息
Settings esSetting = Settings.builder()
.put("cluster.name",clusterName)
.build();
//配置信息Settings自定義,下面設(shè)置為EMPTY
client = new PreBuiltTransportClient(esSetting);
client.addTransportAddresses(transportAddress);
} catch (Exception e) {
logger.error("elasticsearch TransportClient create error!!!", e);
}
return client;
}
}
3说莫、使用單元測試進行驗證
@Autowired
private TransportClient client;
@Test
public void contextLoads() {
System.out.println(client);
//org.elasticsearch.transport.client.PreBuiltTransportClient@6c9b44bf
}
2、接口開發(fā)
1尊勿、新增圖書信息功能開發(fā)
2途事、修改圖書信息功能開發(fā)
3、刪除功能開發(fā)
4娃承、綜合查詢接口開發(fā)
代碼如下:
/**
* ES book索引 控制器
* @author:dufyun
* @version:1.0.0
* @date 2018/8/19
* @update:[日期YYYY-MM-DD] [更改人姓名][變更描述]
*/
@Controller
public class BookController {
@Autowired
private TransportClient client;
/**
* http://localhost:8080/get/book/novel?id=2
* 獲取Es中數(shù)據(jù)
* @param id
* @return
*/
@GetMapping(value = "/get/book/novel")
@ResponseBody
public ResponseEntity getBook(@RequestParam("id") String id) {
if (StringUtils.isEmpty(id)) {
return new ResponseEntity("ID不能為空奏夫!", HttpStatus.NOT_FOUND);
}
GetResponse result = client.prepareGet("book", "novel", id).get();
if (!result.isExists()) {
return new ResponseEntity("資源沒有找到麻削!", HttpStatus.NOT_FOUND);
}
return new ResponseEntity(result.getSource(), HttpStatus.OK);
}
/**
* 添加文檔數(shù)據(jù)
* http://localhost:8080/add/book/novel
* form-data
* @param title
* @param author
* @param word_count
* @param publish_date
* @return
*/
@PostMapping(value = "/add/book/novel")
@ResponseBody
public ResponseEntity addBook(@RequestParam("title") String title, @RequestParam("author") String author,
@RequestParam("word_count") Integer word_count,
@RequestParam("publish_date") String publish_date) {
try {
/**
* 要加 startObject俺祠,否則出現(xiàn) Can not write a field name, expecting a value 錯誤街望!
*/
XContentBuilder builder = XContentFactory.jsonBuilder().startObject().field("title", title)
.field("author", author).field("word_count", word_count)
.field("publish_date", publish_date).endObject();
IndexResponse indexResponse = client.prepareIndex("book", "novel").setSource(builder).get();
return new ResponseEntity(indexResponse.getId(), HttpStatus.INTERNAL_SERVER_ERROR);
} catch (IOException e) {
e.printStackTrace();
new ResponseEntity("內(nèi)部服務(wù)錯誤酝惧!", HttpStatus.INTERNAL_SERVER_ERROR);
}
return new ResponseEntity("插入出錯榴鼎!", HttpStatus.INTERNAL_SERVER_ERROR);
}
/**
* 刪除Es中數(shù)據(jù)
* localhost:8080/del/book/novel?id=sdfhUWUB1-6vN1-K8u5f
* @param id
* @return
*/
@DeleteMapping(value = "/del/book/novel")
@ResponseBody
public ResponseEntity delBook(@RequestParam("id") String id) {
if (StringUtils.isEmpty(id)) {
return new ResponseEntity("ID不能為空!", HttpStatus.NOT_FOUND);
}
DeleteResponse result = client.prepareDelete("book", "novel", id).get();
return new ResponseEntity(result.toString(), HttpStatus.OK);
}
/**
* 更新文檔
*
* @param id
* @param title
* @param author
* @param word_count
* @param publish_date
* @return
*/
@PutMapping(value = "/update/book/novel")
@ResponseBody
public ResponseEntity updateBook(@RequestParam("id") String id,
@RequestParam(value = "title",required = false) String title,
@RequestParam(value = "author",required = false) String author,
@RequestParam(value = "word_count",required = false) Integer word_count,
@RequestParam(value = "publish_date",required = false) String publish_date) {
if (StringUtils.isEmpty(id)) {
return new ResponseEntity("ID不能為空晚唇!", HttpStatus.NOT_FOUND);
}
UpdateRequest updateRequest = new UpdateRequest("book","novel",id);
try {
XContentBuilder builder = XContentFactory.jsonBuilder().startObject();
if (!StringUtils.isEmpty(title)){
builder.field("title", title);
}
if (!StringUtils.isEmpty(author)){
builder.field("author", author);
}
if (!StringUtils.isEmpty(word_count)){
builder.field("word_count", word_count);
}
if (!StringUtils.isEmpty(publish_date)){
builder.field("publish_date", publish_date);
}
builder.endObject();
updateRequest.doc(builder);
UpdateResponse updateResponse = client.update(updateRequest).get();
return new ResponseEntity(updateResponse.getId(), HttpStatus.OK);
} catch (Exception e) {
e.printStackTrace();
return new ResponseEntity("內(nèi)部錯誤巫财!", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
/**
* localhost:8080/query/book/novel
* 復(fù)合查詢接口
* @param title
* @param author
* @param gt_word_conut
* @param lt_word_conut
* @return
*/
@PostMapping(value = "/query/book/novel")
@ResponseBody
public ResponseEntity queryBook(
@RequestParam(value = "title",required = false) String title,
@RequestParam(value = "author",required = false) String author,
@RequestParam(value = "gt_word_conut",defaultValue = "0") int gt_word_conut,
@RequestParam(value = "lt_word_conut",required = false) Integer lt_word_conut) {
BoolQueryBuilder boolQuy = QueryBuilders.boolQuery();
if(!StringUtils.isEmpty(title)){
boolQuy.must(QueryBuilders.matchQuery("title", title));
}
if(!StringUtils.isEmpty(author)){
boolQuy.must(QueryBuilders.matchQuery("author", author));
}
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("word_count").from(gt_word_conut);
if(lt_word_conut != null && gt_word_conut >0){
rangeQueryBuilder.to(lt_word_conut);
}
boolQuy.filter(rangeQueryBuilder);
SearchRequestBuilder searchRequestBuilder = client.prepareSearch("book")
.setTypes("novel")
.setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
.setQuery(boolQuy)
.setFrom(0)
.setSize(10);
SearchResponse searchResponse = searchRequestBuilder.get();
List<Map<String, Object>> lists = new ArrayList<>();
for (SearchHit hit:searchResponse.getHits().getHits()) {
lists.add(hit.getSource());
}
return new ResponseEntity(lists,HttpStatus.OK);
}
}
七、ElasticSearch 總結(jié)
- ES簡介——使用場景(重要性)哩陕,提高競爭力
- 安裝ES-單機-分布式
- 核心基礎(chǔ)概念
- 基本使用方法 ——增刪查改
- 高級查詢語法——重點和難點
- 實戰(zhàn)演練
實戰(zhàn)演練源碼
springboot-elasticsearch
如果您覺得這篇博文對你有幫助平项,請點贊或者喜歡,讓更多的人看到悍及,謝謝闽瓢!
如果帥氣(美麗)、睿智(聰穎)心赶,和我一樣簡單善良的你看到本篇博文中存在問題扣讼,請指出,我虛心接受你讓我成長的批評缨叫,謝謝閱讀椭符!
祝你今天開心愉快!
歡迎訪問我的csdn博客耻姥,我們一同成長销钝!
不管做什么,只要堅持下去就會看到不一樣琐簇!在路上蒸健,不卑不亢!
博客首頁 : http://blog.csdn.net/u010648555
? 每天都在變得更好的阿飛