ElasticSearch課程: https://ke.qq.com/course/315334
tar -zxvf elasticsearch-2.3.4.tar.gz -C ../install/ //解壓到install目錄下
tar -xzvf ./elasticsearch-6.2.4.tar.gz
./bin/elasticsearch -Des.insecure.allow.root=true //允許使用root用戶啓動//無效??
groupadd eszu //創建組
useradd esyonghu -g eszu -p 123456 //創建用戶
chown -R esyonghu:eszu elasticsearch-6.2.4 //-R 遞歸,將elasticsearch目錄下所有文件 改爲esyonghu:eszu 用戶:組
su esyonghu
./bin/elasticsearch -d //正常啓動 es,-d後臺啓動
curl 127.0.0.1:9200 //回車後返回 json數據,則es啓動成功
vi ./config/elasticsearch.yml
noework.host:192.168.25.131 //本機ip
http.port:9200
啓動報錯:
虛擬機內存太小: vi bin/elasticsearch //暫時不用改(視頻沒改)
ES_JAVA_OPTS="-Xms512m-Xmx512m" //修改此項
vi /etc/security/limits.conf //文件末尾加入以下四行
esyonghu soft nofile 65536 //esyonghu是上面新建的用戶名
esyonghu hard nofile 65536
esyonghu soft nproc 4096
esyonghu hard nproc 4096
vi /etc/security/limits.d/20-nproc.conf
esyonghu soft nproc 4096 //把*改爲esyonghu
root soft nproc unlimited //此行不用改
vi /etc/sysctl.conf
vm.max_map_count=655360
sysctl -p //使sysctl配置生效
虛擬機重啓,再啓動es成功。
systemctl stop firewalld.service //centos7.x 關閉防火牆
http:192.168.25.133:9200 //訪問es
-------安裝head插件-------
Head是es的集羣管理工具,可以用於數據的瀏覽和查詢
-------kibana安裝---------
。。。
-------kibana使用---------
//創建索引lib
PUT /lib/
{ "settings":{
"index":{
"number_of_shards":3, //創建3個分片 primary shard主分片
"number_of_replicas":0, //創建0個副本,每個分片有幾個副本(因爲副本不能和主分片在同一個節點上),replica shard副本分片
// 分片+副本 = 主機的個數
}
}
}
PUT /lib2 //使用默認配置創建索引lib2。
//用PUT向lib裏添加文檔
PUT /lib/user/1 //1是id
{"first_name":"Jane",
"last_name":"Smith",
"age":"32",
"about":"I like to build sss",
"interests":["music"]
}
//用POST向lib裏添加文檔
POST /lib/user/ //使用POST設置數據,不用寫id,id自動生成如"nYsisdf2sdfi3ff"
{"first_name":"Douglas",
"last_name":"Fir",
"age":"23",
"about":"I like to build cabinets",
"interests":["forestry"]
}
//獲取文檔
GET _all/_settings_ //獲取所有的索引,如 lib
GET /lib/user/1
GET /lib/user/nYsisdf2sdfi3ff //查看索引lib下user下id爲nYsisdf2sdfi3ff下的所有內容
GET /lib/user/1?_source=age,about //查看索引lib下user下id爲1下的 age和about的內容
//修改文檔
可以使用PUT命令覆蓋已有文檔
POST /lib/user/1/_update //修改索引lib下user下id爲1的文檔
{ "doc":{
"age":30 //修改哪個字段些哪個字段
}
}
//刪除文檔
DELETE /lib/user/1 //刪除索引lib下user下id爲1的文檔
//刪除索引
DELETE
//批量獲取 命令:GET /_mget
例1
GET /_mget //批量獲取3個文檔
{"docs":[
{ "_index":"lib",
"_type":"user", //指定索引中的 類型
"_id":1, //指定類型中的id
"_source":["age","interests"] //指定文檔中的字段
},
{ "_index":"lib",
"_type":"user",
"_id":2,
},
{ "_index":"lib",
"_type":"user",
"_id":3,
}
]
}
例2
GET /lib/user/_mget
{"docs":[
{ "_id":1, //指定類型中的id
"_source":["age","interests"] //指定文檔中的字段
},
{ "_type":"user", //如果要指定類型,必須和上面的類型相同
"_id":2,
}
]
}
例3
GET /lib/user/_mget
{
"ids":["1","2"] //獲取id爲 1 和2 的文檔
}
//使用bulk批量添加文檔
例1
POST /lib2/books/_bulk //添加2個文檔
{"index":{"_id":1}} //指定文檔id //請求頭
{"title":"Java","price":55} //文檔內容 //請求體
{"index":{"_id":2}}
{"title":"Html5","price":35}
例2
POST /lib2/books/_bulk
{"delete":{"_index":"lib2","_type":"books","_id":4}} //刪除/lib2/books/4 這個文檔 //delete沒有請求體
{"create":{"_index":"tt","_type":"ttt","_id":100}} //創建索引tt 創建類型ttt 創建id爲100的文檔
{"name":"lisi"} //創建的請求體
{"index":{"_index":"tt","_type":"ttt"}} //創建文檔,同上。創建索引tt 創建類型ttt ,id由es自動生成
{"name":"zhaoliu"} //創建的請求體
{"update":{"_index":"lib2","_type":"books","_id":"5"}} //修改,
{"doc":{"price":58}} //修改的請求體
PUT /lib/user/4?version=3 //version=3版本號,版本號必須和保存的版本號一樣 才能修改
{"first_name":"Jane",
"last_name":"Lucy",
"age":"25",
}
PUT /lib/user/4?version=3&version_type=external //version_type=external使用外部版本控制,version=5版本號必須比保存的版本號大 才能修改。
{"first_name":"Jane",
"last_name":"Lucy",
"age":"25",
}
//數據類型
string類型包括: text 和 keyword
1.text,用來索引長文本,允許分詞,text類型不能用來排序和聚合
2.keyword,不允許分詞,可以檢索過濾、排序、聚合,keyword類型只能用本身來進行檢索
GET /myindex/article/_mapping //顯示索引下的info,如字段的類型,index:true 分詞 false爲不分詞
GET /myindex/article/_search?q=post_date:2018 //q是關鍵字 查詢條件,post_date是文檔的字段, 2018是要查的值,查不出來,應爲post_date是date類型執行全匹配
GET /myindex/article/_search?q=post_date:2018-05-10 // 可以查出來post_date=2018-05-10的數據
//手動創建mapping
PUT /lib6
{
"settings":{
"number_of_shards":3,
"number_of_replicas":0,
}
"mappings":{
"books":{
"properties":{
"title":{"type":"text"},
"name":{"type":"text","analyzer":"standard"}, //"analyzer":"standard"代表使用standard分詞器
"publish":{"type":"date","index":false}, //"index":false代表不需要建立倒排索引
"price":{"type":"double"},
"number":{"type":"integer"},
}
}
}
}
//查詢
GET /lib3/user/_search?q=name:lisi
GET /lib3/user/_search?q=interests:changge&sort=age:desc //關鍵字sort排序
//查詢結果中有 max_score:0.6756這個是當前搜索相關度的匹配分數
//took 是使用查詢時間,單位毫秒
//successful:3
//failed:0 失敗0次
//term 、 terms 查詢
GET /lib3/user/_search/
{
"query":{ "term":{"name":"zhaoliu"} //查詢name 中存有 zhaoliu的數據
}
}
GET /lib3/user/_search/
{
"query":{ "terms":{"interests":["hejiu","changge"]} //查詢interests 中存有 hejiu或 changge的數據
}
}
GET /lib3/user/_search/
{
"from":0, //從第1個開始取
"size":2, //取2個匹配項
"version":true //顯示版本號
"query":{ "terms":{"interests":["hejiu","changge"]} //查詢interests 中存有 hejiu或 changge的數據
}
}
GET /lib3/user/_search/
{
"query":{ "match":{"interests":"hejiu changge"} //查詢interests 中存有 hejiu或 changge的數據。match可以對查詢條件分詞
}
}
GET /lib3/user/_search/
{
"query":{ "match_all":{} //查詢所有文檔
}
}
GET /lib3/user/_search/
{
"query":{ "multi_match":{
"query":"changge", //查詢changge
"fields":["interests","name"] //在2個字段中查找
}
}
}
GET /lib3/user/_search/
{
"_source":["address","name"] //需要返回的字段,只返回這兩個字段
"query":{ "match_phrase":{"interests":"duanlian,changge"} //短語匹配,匹配含有duanlian,changge兩個詞的數據 並 順序也不能錯
}
}
GET /lib3/user/_search/
{
"query":{ "match_all":{} //查詢所有文檔
},
"_source":{
"includes":["name":"address"], //包含哪些字段
"excludes":["age":"birthday"], //排除哪些字段
}
}
GET /lib3/user/_search/
{
"query":{ "match_all":{} //查詢所有文檔
},
"_source":{
"includes":["name":"addr*"], //包含哪些字段,可以使用通配符
"excludes":["age":"bir*"], //排除哪些字段
}
}
GET /lib3/user/_search/
{
"query":{ "match_all":{} //查詢所有文檔
},
"sort":[
{"age":{"order":"asc"}} //asc升序排序
]
}
GET /lib3/user/_search/
{
"query":{
"match_phrase_prefix":{ //查詢前綴匹配的數據
"name":{"query":"zhao"} //name以zhao爲前綴的數據
}
}
}
GET /lib3/user/_search/
{
"query":{
"range":{ //查詢範圍
"birthday":{
"form":"1990-10-10", //查詢birthday是從1990-10-10到2018-05-01的數據
"to":"2018-05-01"
}
}
}
}
GET /lib3/user/_search/
{
"query":{
"range":{ //查詢範圍
"birthday":{
"form":"1990-10-10", //查詢birthday是從 >=1990-10-10到 <2018-05-01的數據
"to":"2018-05-01",
"include_lower":"true", //包括上屆
"include_upper":"false" //不包括下界
}
}
}
}
GET /lib3/user/_search/
{
"query":{
"wildcard":{ //使用通配符查詢
"name":"li?i" //?代表任意一個字符,*代表任意多個字符
}
}
}
GET /lib3/user/_search/
{
"query":{
"fuzzy":{ //模糊查詢,查詢類似的
"name":"zholiu" //查詢zholiu(中間少個a) 會把zhaoliu查出來
}
}
}
GET /lib3/user/_search/
{
"query":{
"match":{
"interests":"changge"
}
},
"highlight":{ //高亮顯示
"fields":{"interests":{}} //需要高亮顯示的字段
}
}
..."name":{"type":"text","analyzer":"ik_max_word"} //"analyzer":"ik_max_word"代表細粒度的分詞
term query 會去倒排索引中尋找確切的term,不知道分詞器的存在,適合keywor、number、date的查詢
match 知道分詞器的存在,
Get /_cat/indices //列出所有索引
GET _cat/health //查看集羣健康狀態 綠色是正常,yellow是 副本不全,red是缺少分片 不可用狀態。 ***
副本是可以處理查詢請求的。 ***
_index 索引命名必須是小寫,不能包含逗號、不能下劃線開頭 ***
_type 一個索引下只能有一個type,類型名可以大小寫,不能下劃線開頭,不能有逗號 ***
_id 文檔唯一標識,和索引、類型組合在一起唯一標識了一個文檔,可以手動指定也可以 es生成。post方式保存值 自動生成
PUT和POST都可以修改文檔內容,post比put方式網絡傳輸次數少,從而向能高,post發生衝突的可能性小,put發生衝突的可能性較大。***
//使用腳本的寫法操作文檔
GET /lib/user/4/_update
{
"script":"ctx._source.age+=1" //ctx是固定寫法,_source代表所有的字段,將年齡+1 。冒號後面是寫的執行腳本
}
GET /lib/user/4/_update
{
"script":"ctx._source.last_name+='hehe'" //ctx是固定寫法,名稱後+hehe
}
GET /lib/user/4/_update
{
"script":{"source":"ctx._source.interests.add(params.tag)", //ctx是固定寫法,params是參數的固定寫法 tag是參數名稱,interests是數組 用add或remove增加或刪除
"params":{"tag":"football"} //定義參數值
}
}
GET /lib/user/4/_update
{
"script":{"source":"ctx._source.interests.remove(ctx._source.interests.indexOf(params.tag))", //從數組中刪除一項,indexOf獲取數組下標
"params":{"tag":"football"} //定義參數值
}
}
#刪除文檔
GET /lib/user/4/_update
{
"script":{ "source":"ctx.op=ctx._source.age==params.count?'delete':'none'" , //ctx.op代表作什麼操作 固定寫法。如果當前文檔age==22 則刪除當前文檔,22只能以參數的形式傳入
"params":{"count":22} //定義參數值
}
}
#upsert操作,如果文檔不存在 則會初始化upsert中的數據
GET /lib/user/4/_update
{
"script":"ctx._source.age+=1" //如果文檔/lib/user/4存在 則執行此行,文檔不存在不執行此行 執行upsert
"upsert":{
"first_name":"Jane",
"last_name":"Lucy",
"age":20
}
}
#多線程更新使用,解決一致性
POST /lib/user/4/_update?retry_on_conflict=3&version=5 //同上面GET用法一樣,只是多個進程併發處理時使用,retry_on_conflict=3重複處理3次,version=5版本控制樂觀鎖。
查詢結果:
{
"took":11, //查詢耗時11毫秒
"timed_out":false, //是否超時,默認是沒有超時時間的,除非在get後面家 timeout=10ms
"_shards":{ //shard相關
"total":3, //搜索了3個shard
"successful":3, //成功3個shard
"skipped":0,
"failed":0
},
"hits":{ //查詢結果在這裏,默認最多顯示前10個查詢結果
"total":4, //總共查詢到4個結果
"max_score":2.3316, //最大評分
"hits":[ //查詢的結果
{
"_index":"lib3", //索引名稱
"_type":"user", //類型名稱 ,一個索引下只能有一個類型
"_id":"2", //id名稱
"_score":"2.3316", //相關度評分
"_source":{
"name":"zhaoming",
"address":"bei jing ",
"age":"20",
}
},{
...同上
}
]
}
}
GET /_all/user,items/_search //查詢所有類型下的 user和items類型
GET /_all/_search
GET /lib,lib4/user,items/_search //查詢lib和lib4索引 下的 user和items類型
GET /*3,*4/_search //查詢索引爲 3或4結尾的所有數據
es支持分頁查詢叫 deep paging,很消耗內存,儘量減少使用
GET /_search?from=0&size=3 //分頁查詢,從第一條數據 開始取 3條數據
日期類型不會進行分詞,只能精確查詢
GET /myindex/article/_search?q=post_date:2018-05-10 //q是關鍵字 查詢,查詢post_date字段,查詢post_date:2018-05-10的數據。
GET /myindex/article/_search?q=html,document //q查詢,沒有寫在哪個字段裏查詢,則查所有字段裏是否 含有html或document 的數據
"copy_to":"fulcontent" //自動將文檔下所有的 文本類型字段拷貝到 fulcontent字段下,fulcontent爲copy_to字段
copy_to 字段只能拷貝文本類型,日期 數字類型不能拷貝進來
GET /myindex/article/_search?q=fulcontent:html,document //fulcontent可以當字段使用
字符串類型分爲兩種,一種 text類型 可以被分詞,一種keyword類型 不能被分詞
分詞類型的文本 是不能排序的,不分詞的類型纔可以排序。
"interests":{ //interests爲字段名 的mapping,以下分配了兩個類型 並建立兩個索引
"type":"text", //text類型,查詢使用。建立了倒排索引
"fields":{
"raw":{"type":"keyword"} //raw爲keyword類型,排序用 。建立了正拍索引
},
"fielddata":true //也要設置,對分詞自動無效?
}
GET /lib3/user/_search{ //查詢 排序
"query":{
"match_all":{}
},
"sort":[{
"interests.raw":{"order":"desc"} //使用字段interests 裏面的raw進行排序
}]
}
"doc_values":true //把字段設置爲可排序的,默認是true,對分詞字段(text類型)無效 text不能排序。PUT中使用
GET /lib3/user/_search?scroll=1m{ //1秒內返回查詢
"query":{
"match_all":{}
},"sort":["_doc"], //按照doc value 索引排序(不按照評分排序)
"size":3 //返回三個
} //此查詢會返回scroll_id 記錄快照,用於下次查詢 只要知名scroll_id就可以繼續查詢。如下
GET /_search/scroll{
"scroll":"1m",
"scroll_id":"sdfsdfewrddvcd==" //scroll_id 是上次查詢返回的id,從這個id開始繼續查詢。
}
"dynamic":"strict" //文檔中出現不存在的字段如何處理,true是自動映射,false忽略,strict報錯。PUT中使用
"date_detection":false //將‘2018-01-10’此類數據自動識別爲日期類型,如果不需要識別爲日期類型則加此設置,默認爲true。PUT中使用
PUT /my_index{
"mappings":{
"my_type":{
"dynamic_templates"[{
"en":{
"match":"*_en", //如果自動名 以_en結尾 則使用此模板
"match_mapping_type":"string",
"mapping":{
"type":"text", //文檔類型text
"analyzer":"english" //使用分詞器 english ,(默認分詞器是standard,english分詞器對於a an is這鐘詞 不分詞 使用查詢查不出來的)
}
}
}]
} }}
重建索引
字段的類型一旦確定 就不能修改,只能新建索引,再將舊數據導入到新索引內。
PUT /index1/_alias/index2 //新建別名 index2指向index1
GET index1/type1/_search?scroll=1m{ //批量查詢出數據
"query":{
"match_all":{}
},
"sort":["_doc"],
"size":2
}
POST /_bulk //使用bulk批量添加到新的索引中
{"index":{"_index":"newindex","_type":"type1","_id":"1"}}
{"content":"1988-09-01"}
POST /_aliases{ "actions":[ //修改別名關聯
{"remove":{"index":"index1","alias":"index2"}}, //取消別名關聯
{"add":{"index":"newindex","alias":"index2"}} //添加別名關聯
]
}
"title"{
"type":"test",
"analyzer":"ik_max_word" //使用中文分詞器,ik(ik要事先安裝插件)
}
java中使用elasticsearch pom.xml配置
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>5.4.2</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>5.4.2</version>
</dependency>
//設置es名稱
Settings setting = Settings.builder().put("cluster.name","my_es").build();
//創建訪問es客戶端
TransportClient client = new PreBuiltTransportClient(settings).addTransportAddress(new TransportAddress(InetAddress.getByName("192.168.0.34"),9200));
//數據查詢
GetResponse response = client.prepareGet("lib3","user","1");
//得到查詢出的數據
Systen.out.prinln(response.getSourceAsString());
//修改
UpdateRsquest request = new UpdateRequest();
request.index("index1").type("blog").id("10").doc(XContentFactory.jsonBuilder().startObject().field("title","單利模式").endObject());
UpdateResponse response = client.update(request).get();//執行修改
//文檔添加
IndexRequest request1 = new IndexRequest("index1","type","8").source(XContentFactory.jsonBuilder().startObject().field("id","2").field("title","java設計模式").field("content","在不必改變文件").field("postdate","2018-05-20").endObject());
//index1/blog/8 文檔不存在則添加,文檔存在則修改
UpdateResponse request2 = new UpdateResponse("index1","blog","8")
.doc(
XContentFactory.jsonBuilder().startObject().field("title","單利模式").endObject()
).upsert(request1); //upsert 有責修改,沒有則添加
UpdateResponse response = client.update(request2).get(); //執行修改
client.close();