1挥唠、索引的增刪改
創(chuàng)建索引的示例
PUT /my_index
{
??"settings": {
????"number_of_shards": 1,
????"number_of_replicas": 0
??},
??"mappings": {
????"my_type": {
??????"properties": {
????????"my_field": {
??????????"type": "text"
????????}
??????}
????}
??}
}
修改索引
PUT /my_index/_settings
{
????"number_of_replicas": 1
}
刪除索引
DELETE /my_index
DELETE /index_one,index_two
DELETE /index_*
DELETE /_all
防止使用delete/_all,可以在elasticsearch.yml里面修改action.destructive_requires_name: true
2、分詞器設置
(1)焕议、默認的分詞器standard
standard tokenizer:以單詞邊界進行切分
standard token filter:什么都不做
lowercase token filter:將所有字母轉換為小寫
stop token filer(默認被禁用):移除停用詞宝磨,比如a the it等等
(2)、修改分詞器的設置
設置一個索引盅安,啟用english停用詞默認token filter唤锉,這樣這個索引就是按這種來分詞的
PUT /my_index
{
??"settings": {
????"analysis": {
??????"analyzer": {
????????"es_std": {
??????????"type": "standard",
??????????"stopwords": "_english_"
????????}
??????}
????}
??}
}
(3)、定制化自己的分詞器
PUT /my_index
{
??"settings": {
????"analysis": {
??????"char_filter": {
????????"&_to_and": {
??????????"type": "mapping",
??????????"mappings": ["&=> and"]
????????}
??????},
??????"filter": {
????????"my_stopwords": {
??????????"type": "stop",
??????????"stopwords": ["the", "a"]
????????}
??????},
??????"analyzer": {
????????"my_analyzer": {
??????????"type": "custom",
??????????"char_filter": ["html_strip", "&_to_and"],
??????????"tokenizer": "standard",
??????????"filter": ["lowercase", "my_stopwords"]
????????}
??????}
????}
??}
}
GET /my_index/_analyze
{
??"text": "tom&jerry are a friend in the house, <a>, HAHA!!",
??"analyzer": "my_analyzer"
}
PUT /my_index/_mapping/my_type
{
??"properties": {
????"content": {
??????"type": "text",
??????"analyzer": "my_analyzer"
????}
??}
}
3别瞭、type相關知識
type窿祥,是一個index中用來區(qū)分類似的數據的,類似的數據蝙寨,但是可能有不同的fields晒衩,而且有不同的屬性來控制索引建立、分詞器籽慢。
field的value浸遗,在底層的lucene中建立索引的時候,全部是二進制類型箱亿,不區(qū)分類型的跛锌,lucene是沒有type的概念的,在document中,實際上將type作為一個document的field來存儲髓帽,即_type菠赚,es通過_type來進行type的過濾和篩選。
一個index中的多個type郑藏,實際上是放在一起存儲的衡查,因此一個index下,不能有多個type重名必盖,而類型或者其他設置不同的拌牲,因為那樣是無法處理的
例如:
PUT /my_index/my_type/1
{
??"name": "geli kongtiao",
??"price": 1999.0,
??"service_period": "one year"
}
PUT /my_index/my_type/2
{
??"name": "aozhou dalongxia",
??"price": 199.0,
??"eat_period": "one week"
}
在底層的存儲是這樣子的。歌粥。塌忽。。
{
???"my_index": {
??????"mappings": {
????????"_type": {
??????????"type": "string",
??????????"index": "not_analyzed"
????????},
????????"name": {
??????????"type": "string"
????????}
????????"price": {
??????????"type": "double"
????????}
????????"service_period": {
??????????"type": "string"
????????}
????????"eat_period": {
??????????"type": "string"
????????}
??????}
???}
}
{
??"_type": "elactronic_goods",
??"name": "geli kongtiao",
??"price": 1999.0,
??"service_period": "one year",
??"eat_period": ""
}
{
??"_type": "fresh_goods",
??"name": "aozhou dalongxia",
??"price": 199.0,
??"service_period": "",
??"eat_period": "one week"
}
最佳實踐失驶,將類似結構的type放在一個index下土居,這些type應該有多個field是相同的
假如說,你將兩個type的field完全不同嬉探,放在一個index下擦耀,那么就每條數據都至少有一半的field在底層的lucene中是空值,會有嚴重的性能問題
4涩堤、mapping相關知識
Mapping相關屬性設置有那些統(tǒng)稱root object
就是某個type對應的mapping json眷蜓,包括了properties,metadata(_id定躏,_source账磺,_type),settings(analyzer)痊远,其他settings(比如include_in_all)這些
格式:
PUT /my_index
{
??"mappings": {
????"my_type": {
??????"properties": {}
????}
??}
}
(1)properties
PUT /my_index/_mapping/my_type
{
“properties”:{
“title”:{
“type”:”text”
}
}
}
(2)垮抗、_source
好處
(1)查詢的時候,直接可以拿到完整的document碧聪,不需要先拿document id冒版,再發(fā)送一次請求拿document
(2)partial update基于_source實現(xiàn)
(3)reindex時,直接基于_source實現(xiàn)逞姿,不需要從數據庫(或者其他外部存儲)查詢數據再修改
(4)可以基于_source定制返回field
(5)debug query更容易辞嗡,因為可以直接看到_source
如果不需要上述好處,可以禁用_source
PUT /my_index/_mapping/my_type2
{
??"_source": {"enabled": false}
}
(3)滞造、_all
將所有field打包在一起续室,作為一個_all field,建立索引谒养。沒指定任何field進行搜索時挺狰,就是使用_all field在搜索。
PUT /my_index/_mapping/my_type3
{
??"_all": {"enabled": false}
}
也可以在field級別設置include_in_all field,設置是否要將field的值包含在_all field中
PUT /my_index/_mapping/my_type4
{
??"properties": {
????"my_field": {
??????"type": "text",
??????"include_in_all": false
????}
??}
}
5丰泊、定制自動化策略
?
1薯定、定制dynamic策略
"dynamic": "strict"
true:遇到陌生字段,就進行dynamic mapping
false:遇到陌生字段瞳购,就忽略
strict:遇到陌生字段话侄,就報錯
PUT /my_index
{
??"mappings": {
????"my_type": {
??????"dynamic": "strict",
??????"properties": {
????????"title": {
??????????"type": "text"
????????},
????????"address": {
??????????"type": "object",
??????????"dynamic": "true"
????????}
??????}
????}
??}
}
-------這樣設置會報錯
PUT /my_index/my_type/1
{
??"title": "my article",
??"content": "this is my article",
??"address": {
????"province": "guangdong",
????"city": "guangzhou"
??}
}
6、定制dynamic mapping策略
(1)date_detection
默認會按照一定格式識別date学赛,比如yyyy-MM-dd年堆。但是如果某個field先過來一個2017-01-01的值,就會被自動dynamic mapping成date罢屈,后面如果再來一個"hello world"之類的值嘀韧,就會報錯〔疲可以手動關閉某個type的date_detection,如果有需要译蒂,自己手動指定某個field為date類型曼月。如果當自己動成date的不是自己想要的,在生JAVA在使用的情況下怎么處理呢柔昼?下面講解
PUT /my_index/_mapping/my_type
{
????"date_detection": false
}
(2)定制自己的dynamic mapping template(type level)
PUT /my_index
{
????"mappings": {
????????"my_type": {
????????????"dynamic_templates": [
????????????????{ "en": {
??????????????????????"match": ?????????????"*_en",
??????????????????????"match_mapping_type": "string",
??????????????????????"mapping": {
??????????????????????????"type": ??????????"string",
??????????????????????????"analyzer": ??????"english"
??????????????????????}
????????????????}}
????????????]
}}}
PUT /my_index/my_type/1
{
??"title": "this is my first article"
}
PUT /my_index/my_type/2
{
??"title_en": "this is my first article"
}
GET /my_index/my_type/_search
{
"query": {
????"match": {
??????"title": "is"http://或者title_en
????}
??}
}
查詢時哑芹,title沒有匹配到任何的dynamic模板,默認就是standard分詞器捕透,不會過濾停用詞聪姿,is會進入倒排索引,用is來搜索是可以搜索到的
title_en匹配到了dynamic模板乙嘀,就是english分詞器末购,會過濾停用詞,is這種停用詞就會被過濾掉虎谢,用is來搜索就搜索不到了
(3)定制自己的default mapping template(index level)
PUT /my_index
{
????"mappings": {
????????"_default_": {
????????????"_all": { "enabled": ?false }
????????},
????????"blog": {
????????????"_all": { "enabled": ?true ?}
????????}
????}
}
7盟榴、重建索引
一個field的設置是不能被修改的,如果要修改一個Field婴噩,那么應該重新按照新的mapping擎场,建立一個index,然后將數據批量查詢出來几莽,重新用bulk api寫入index中
問題:
一開始迅办,依靠dynamic mapping,插入數據章蚣,但是不小心有些數據是2017-01-01這種日期格式的站欺,所以title這種field被自動映射為了date類型,實際上它應該是string類型的,當后期向索引中加入string類型的title值的時候镊绪,就會報錯匀伏。
解決:
(1)、進行reindex蝴韭,也就是說够颠,重新建立一個索引,將舊索引的數據查詢出來榄鉴,再導入新索引履磨,如果說舊索引的名字,是old_index庆尘,新索引的名字是new_index剃诅,終端java應用,已經在使用old_index在操作了驶忌,難道還要去停止java應用矛辕,修改使用的index為new_index,才重新啟動java應用嗎付魔?這個過程中聊品,就會導致java應用停機,可用性降低几苍。
(2)翻屈、所以說,給java應用一個別名妻坝,這個別名是指向舊索引的伸眶,java應用先用著,java應用先用goods_index alias來操作刽宪,此時實際指向的是舊的old_index
PUT /old_index/_alias/goods_index
(3)厘贼、新建一個index,調整其title的類型為string
PUT /my_index_new
{
??"mappings": {
????"my_type": {
??????"properties": {
????????"title": {
??????????"type": "text"
????????}
??????}
????}
??}
}
(4)纠屋、使用scroll api將數據批量查詢出來
GET /my_index/_search?scroll=1m
{
????"query": {
????????"match_all": {}
????},
????"sort": ["_doc"],
????"size": ?1
}
{
??"_scroll_id": "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAADpAFjRvbnNUWVZaVGpHdklqOV9zcFd6MncAAAAAAAA6QRY0b25zVFlWWlRqR3ZJajlfc3BXejJ3AAAAAAAAOkIWNG9uc1RZVlpUakd2SWo5X3NwV3oydwAAAAAAADpDFjRvbnNUWVZaVGpHdklqOV9zcFd6MncAAAAAAAA6RBY0b25zVFlWWlRqR3ZJajlfc3BXejJ3",
??"took": 1,
??"timed_out": false,
??"_shards": {
????"total": 5,
????"successful": 5,
????"failed": 0
??},
??"hits": {
????"total": 3,
????"max_score": null,
????"hits": [
??????{
????????"_index": "my_index",
????????"_type": "my_type",
????????"_id": "2",
????????"_score": null,
????????"_source": {
??????????"title": "2017-01-02"
????????},
????????"sort": [
??????????0
????????]
??????}
????]
??}
}
(5)采用bulk api將scoll查出來的一批數據涂臣,批量寫入新索引
POST /_bulk
{ "index": ?{ "_index": "my_index_new", "_type": "my_type", "_id": "2" }}
{ "title": ???"2017-01-02" }
這里有個疑惑,難不成一條一條處理售担?
[if !supportLists](1)[endif]赁遗、將goods_index alias切換到my_index_new上去,java應用會直接通過index別名使用新的索引中的數據族铆,java應用程序不需要停機岩四,零提交,高可用
POST /_aliases
{
????"actions": [
????????{ "remove": { "index": "my_index", "alias": "goods_index" }},
????????{ "add": ???{ "index": "my_index_new", "alias": "goods_index" }}
????]
}
8哥攘、基于alias對client透明切換index
PUT /my_index_v1/_alias/my_index
client對my_index進行操作
reindex操作剖煌,完成之后材鹦,切換v1到v2
POST /_aliases
{
????"actions": [
????????{ "remove": { "index": "my_index_v1", "alias": "my_index" }},
????????{ "add": ???{ "index": "my_index_v2", "alias": "my_index" }}
????]
}
9、倒排索引知識補充
倒排索引的結構
(1)包含這個關鍵詞的document list
(2)包含這個關鍵詞的所有document的數量:IDF(inverse document frequency)
(3)這個關鍵詞在每個document中出現(xiàn)的次數:TF(term frequency)
(4)這個關鍵詞在這個document中的次序
(5)每個document的長度:length norm
(6)包含這個關鍵詞的所有document的平均長度
倒排索引不可變的好處:
(1)不需要鎖耕姊,提升并發(fā)能力桶唐,避免鎖的問題
(2)數據不變,一直保存在os cache中茉兰,只要cache內存足夠
(3)filter cache一直駐留在內存尤泽,因為數據不變
(4)可以壓縮,節(jié)省cpu和io開銷
倒排索引不可變的壞處:
(1)每次都要重新構建整個索引