一. 前言
最近閑賦在家, 准備對以前項目中使用的一些技術, 進行一次總結. 故有了這篇小文
elasticsearch在管理類項目中, 用的少, 但是在商品類項目中, 用的還是很多的. 我們在項目中, 會將 canal 配合着elasticsearch來使用.
(canal 會將自己偽裝成 mysql 的slave, 他會去讀取 mysql 日志, 然后可以進行 elasticsearch 的更新操作. 這種方式是一種實時的方式, 對我們的項目沒有侵入性, 還是比較好的一種方式)
(我們項目用的是es6, canal目前穩定版本也只是支持到 es6, 如果是 es7, 謹慎使用canal)
二. 工具
自己在使用elasticsearch的時候, 造數據是一件比較麻煩的事, 費事又費力. 這里推薦使用狂神寫的一款爬蟲.
造數據就比較輕松了.
這里還是用到了一款軟件, 來對elasticsearch 進行查詢和操作: kibana
狂神說java : https://space.bilibili.com/95256449?spm_id_from=333.788.b_765f7570696e666f.2
工具地址: https://gitee.com/elvinle/jd_pachong.git
es這個軟件是歪果仁開發的, 所以對中文的支持並不好, 我們還需要下載一個 ik 分詞器: https://github.com/medcl/elasticsearch-analysis-ik
三. 軟件安裝:
version: '3'
services:
elasticsearch:
image: elasticsearch:7.6.2
container_name: elasticsearch
user: root
environment:
- "cluster.name=elasticsearch" #設置集群名稱為elasticsearch
- "discovery.type=single-node" #以單一節點模式啟動
- "ES_JAVA_OPTS=-Xms512m -Xmx512m" #設置使用jvm內存大小
volumes:
- /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins #插件文件掛載
- /mydata/elasticsearch/data:/usr/share/elasticsearch/data #數據文件掛載
ports:
- 9200:9200
- 9300:9300
kibana:
image: kibana:7.6.2
container_name: kibana
links:
- elasticsearch:es #可以用es這個域名訪問elasticsearch服務
depends_on:
- elasticsearch #kibana在elasticsearch啟動之后再啟動
environment:
- "elasticsearch.hosts=http://es:9200" #設置訪問elasticsearch的地址
ports:
- 5601:5601
這里采用 docker-compose 的方式, docker 和 docker-compose 的安裝, 就不在這里寫了.
我們將 ik 分詞器下載下來之后, 解壓到 /mydata/elasticsearch/plugins/ik 目錄中
四. 建索引庫
建索引庫, 類似於mysql建表一樣. es有兩種建庫方式:
1). es默認建庫, 無需開發人員手動指定字段信息
2). 手動建庫(推薦)
1. 自動建庫的方式:
PUT /索引名/_doc/文檔id 文檔內容 json 串
這種方式雖然方便, 但是在后面進行term索引的時候, 會有一定的問題.
因為這種默認的方式, 並不會進行ik分詞
可以通過 GET /lisen 來看一下索引庫結構:
{
"lisen" : {
"aliases" : { },
"mappings" : {
"properties" : {
"age" : {
"type" : "long"
},
"desc" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"hobby" : { "type" : "text", "fields" : { "keyword" : { "type" : "keyword", "ignore_above" : 256 } } },
"name" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"work" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
},
"settings" : {
"index" : {
"creation_date" : "1603160907639",
"number_of_shards" : "1",
"number_of_replicas" : "1",
"uuid" : "5Yt2WsBfQK2Iv2IAEDmN1Q",
"version" : {
"created" : "7060299"
},
"provided_name" : "lisen"
}
}
}
}
2. 手動建庫(推薦)
#建表語句, img, price 都是默認的, title進行了ik分詞處理, 否則在查詢的時候, 對中文不是很支持
PUT /jd_goods
{
"mappings": {
"properties" : {
"img" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"price" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"title" : { "type" : "text", "analyzer": "ik_max_word" }
}
}
}
后續的操作, 我會對 jd_goods 庫和 lisen 庫進行. 比較的方式看, 會比較明顯.
jd_goods的數據, 是從jd爬取的, 比較方便, 所以這邊不對 jd_goods 庫進行增刪改 操作.
五. 增刪改查
1. 前置知識
es推薦使用 rest 調用接口的方式來操作. 其操作方式有以下幾種:
#PUT 索引名/_doc/文檔id 創建文檔-指定id #POST 索引名/_doc 創建文檔-隨機id #POST 索引名/_update/文檔id 修改文檔 #DELETE 索引名/_doc/文檔id 刪除文檔 #GET 索引名/_doc/文檔id 通過id獲取文檔 #POST 索引名/_search 查詢所有數據
常用數據類型有以下幾種:
#字符串類型 text keyword #數值類型 long integer short byte double float, half float, scaled float #日期類型 data #布爾類型 boolean #二進制類型 binary
附初始數據語句:
PUT /lisen/_doc/1 { "name":"elvin", "age": 29, "work": "java軟件開發工程師", "hobby":["籃球", "羽毛球", "乒乓球", "游泳"], "desc": "一個喜歡運動, 愛老婆的boy" } PUT /lisen/_doc/2 { "name":"john", "age": 27, "work": "前端開發工程師", "hobby":["騎電瓶車", "羽毛球"], "desc": "一個很剛的帥小伙" } PUT /lisen/_doc/3 { "name":"sury", "age": 35, "work": "測試工程師", "hobby":["帶娃", "乒乓球"], "desc": "一個很有想法的小伙" } PUT /lisen/_doc/4 { "name":"主公", "age": 35, "work": "測試工程師", "hobby":["帶飯", "游泳"], "desc": "一個搖擺不定的小伙" }
2. GET
GET /庫名
可以獲取建庫信息
GET /庫名/_doc/文檔id
根據文檔id獲取信息, 相當於 select * from 庫名 where id = #{id}
3. DELETE
DELETE /庫名
直接刪索引庫, 刪除之后, 再 get 就回報錯
此時再 get 一下
es會返回 404
DELETE /庫名/_doc/文檔id
根據文檔id進行刪除
此時再 get 一下
會發現 found = false 了, 找不到了
4. UPDATE
1) PUT方式修改 - 全量修改
2) POST方式修改 - 可以全量, 也可以非全量
PUT /庫名/_doc/文檔id
PUT 在 restFull 里面代表兩個意思: add 和 update, 當沒有id時, 新增, 當有id時修改
在這里, 也是一樣的. 當有指定的id時, 修改, 當沒有指定的id時, 新增
這是一種全量修改方式
這里我沒有寫 desc 字段, 然后改了work字段和hobby字段. 此時再get, 看看結果
確實是全量修改
POST /庫名/_doc/文檔id
這也是一種全量方式, 結果和 PUT 是一樣的. 同樣的, post也可以新增數據.
POST /庫名/_update/文檔id
非全量方式, 他只有修改的功能, 沒有新增文檔的功能
如果只有全量方式, 那豈不是很不方便.
再get一下:
別的字段都在, 且沒有發生任何變化
六 復雜查詢
復雜查詢可以實現 分頁, 排序, 高亮, 模糊查詢, 精確查詢
查詢有兩種方式, 一種是拼參的方式, 另一種是 GET /庫名/_search{} 的方式
拼參方式
GET /庫名/_search
#_source顯示那些列
可以直接寫數組, 如: ["name", "age", "work", "hobby", "desc"]
還可以設置 includes 和 excludes, 如:
"_source": { "includes": ["name", "age", "work", "hobby", "desc"], "excludes": ["work", "hobby"] }
#sort 排序
對字段進行排序, 如:
"sort": [ { "age": { "order": "desc" } } ]
分頁
#from 相當於pageNo
#size 相當於pageSize, 默認20
將上面組合起來, 查詢看看: