什么是搜索般哼?
百度:我們比如說想找尋任何的信息的時候蒸眠,就會上百度去搜索一下杆融,比如說找一部自己喜歡的電影脾歇,或者說找一本喜歡的書,或者找一條感興趣的新聞(提到搜索的第一印象)徽惋。百度 != 搜索
1)互聯(lián)網(wǎng)的搜索:電商網(wǎng)站座韵,招聘網(wǎng)站誉碴,新聞網(wǎng)站,各種app
2)IT系統(tǒng)的搜索:OA軟件代咸,辦公自動化軟件呐芥,會議管理奋岁,日程管理,項目管理滨攻。
搜索光绕,就是在任何場景下,找尋你想要的信息欣尼,這個時候景埃,會輸入一段你要搜索的關(guān)鍵字谷徙,然后就期望找到這個關(guān)鍵字相關(guān)的有些信息
如果用數(shù)據(jù)庫做搜索會怎么樣驯绎?
用數(shù)據(jù)庫來實現(xiàn)搜索剩失,是不太靠譜的拴孤。通常來說,性能會很差的鞭执。
什么是全文檢索和Lucene芒粹?
(1)全文檢索化漆,倒排索引
全文檢索 是指計算機索引程序通過掃描文章中的每一個詞,對每一個詞建立一個索引疙赠,指明該詞在文章中出現(xiàn)的次數(shù)和位置棺聊,當用戶查詢時贞谓,檢索程序就根據(jù)事先建立的索引進行查找祟同,并將查找的結(jié)果反饋給用戶的檢索方式。這個過程類似于通過字典中的檢索字表查字的過程。全文搜索搜索引擎數(shù)據(jù)庫中的數(shù)據(jù)贰锁。
倒排索引原理簡介:
(2)lucene
lucene豌熄,就是一個jar包锣险,里面包含了封裝好的各種建立倒排索引芯肤,以及進行搜索的代碼崖咨,包括各種算法掩幢。我們就用java開發(fā)的時候际邻,引入lucene jar芍阎,然后基于lucene的api進行去進行開發(fā)就可以了谴咸。
什么是Elasticsearch岭佳?
Elasticsearch珊随,基于lucene鲫凶,隱藏復雜性,提供簡單易用的restful api接口、java api接口(還有其他語言的api接口)掸屡。
關(guān)于elasticsearch的一個傳說仅财,有一個程序員失業(yè)了谦炒,陪著自己老婆去英國倫敦學習廚師課程。程序員在失業(yè)期間想給老婆寫一個菜譜搜索引擎,覺得lucene實在太復雜了爹耗,就開發(fā)了一個封裝了lucene的開源項目潭兽,compass。后來程序員找到了工作,是做分布式的高性能項目的铸本,覺得compass不夠箱玷,就寫了elasticsearch椅亚,讓lucene變成分布式的系統(tǒng)舱污。
Elasticsearch是一個實時分布式搜索和分析引擎媚赖。它用于全文搜索、結(jié)構(gòu)化搜索捻撑、分析番捂。
- 全文檢索:將非結(jié)構(gòu)化數(shù)據(jù)中的一部分信息提取出來,重新組織,使其變得有一定結(jié)構(gòu),然后對此有一定結(jié)構(gòu)的數(shù)據(jù)進行搜索犁河,從而達到搜索相對較快的目的宾符。
- 結(jié)構(gòu)化檢索:我想搜索商品分類為日化用品的商品都有哪些,select * from products where category_id='日化用品'
- 數(shù)據(jù)分析:電商網(wǎng)站则奥,最近7天牙膏這種商品銷量排名前10的商家有哪些读处;新聞網(wǎng)站井辜,最近1個月訪問量排名前3的新聞版塊是哪些
Elasticsearch的適用場景
- 維基百科粥脚,類似百度百科刷允,牙膏,牙膏的維基百科糯而,全文檢索像寒,高亮,搜索推薦阐虚。
- The Guardian(國外新聞網(wǎng)站),類似搜狐新聞,用戶行為日志(點擊避矢,瀏覽审胸,收藏,評論)+ 社交網(wǎng)絡(luò)數(shù)據(jù)(對某某新聞的相關(guān)看法)碍庵,數(shù)據(jù)分析静浴,給到每篇新聞文章的作者双絮,讓他知道他的文章的公眾反饋(好得问,壞抚岗,熱門,垃圾认境,鄙視亩冬,崇拜)。
- Stack Overflow(國外的程序異常討論論壇)营袜,IT問題荚板,程序的報錯,提交上去免绿,有人會跟你討論和回答袱吆,全文檢索距淫,搜索相關(guān)問題和答案蓬衡,程序報錯了狰晚,就會將報錯信息粘貼到里面去,搜索有沒有對應的答案
- GitHub(開源代碼管理)秒咐,搜索上千億行代碼。
- 國內(nèi):站內(nèi)搜索(電商帮孔,招聘晤斩,門戶揩页,等等)爆侣,IT系統(tǒng)搜索(OA兔仰,CRM忍法,ERP勉失,等等)乱凿,數(shù)據(jù)分析(ES熱門的一個使用場景)。
Elasticsearch的特點
- 可以作為一個大型分布式集群(數(shù)百臺服務(wù)器)技術(shù)段审,處理PB級數(shù)據(jù),服務(wù)大公司型凳;也可以運行在單機上甘畅,服務(wù)小公司
- Elasticsearch不是什么新技術(shù),主要是將全文檢索槐脏、數(shù)據(jù)分析以及分布式技術(shù),合并在了一起牌废,才形成了獨一無二的ES鸟缕;lucene(全文檢索)授段,商用的數(shù)據(jù)分析軟件(也是有的),分布式數(shù)據(jù)庫(mycat)
- 對用戶而言模燥,是開箱即用的,非常簡單牺汤,作為中小型的應用补胚,直接3分鐘部署一下ES,就可以作為生產(chǎn)環(huán)境的系統(tǒng)來使用了瓶逃,數(shù)據(jù)量不大,操作不是太復雜
- 數(shù)據(jù)庫的功能面對很多領(lǐng)域是不夠用的(事務(wù),還有各種聯(lián)機事務(wù)型的操作)靶病;特殊的功能嫡秕,比如全文檢索驾凶,同義詞處理,相關(guān)度排名,復雜數(shù)據(jù)分析浮声,海量數(shù)據(jù)的近實時處理;Elasticsearch作為傳統(tǒng)數(shù)據(jù)庫的一個補充屉符,提供了數(shù)據(jù)庫所不能提供的很多功能
Elasticsearch的核心概念
近實時
近實時矗钟,兩個意思,從寫入數(shù)據(jù)到數(shù)據(jù)可以被搜索到有一個小延遲(大概1秒)秸应;基于es執(zhí)行搜索和分析可以達到秒級。
Cluster(集群)
集群包含多個節(jié)點,每個節(jié)點屬于哪個集群是通過一個配置(集群名稱贿条,默認是elasticsearch)來決定的,對于中小型應用來說公黑,剛開始一個集群就一個節(jié)點很正常人断。
集群是由一個或多個擁有相同cluster.name配置的節(jié)點組成朝蜘。
Node(節(jié)點)
集群中的一個節(jié)點,節(jié)點也有一個名稱(默認是隨機分配的)谱醇,節(jié)點名稱很重要(在執(zhí)行運維管理操作的時候),默認節(jié)點會去加入一個名稱為“elasticsearch”的集群副渴,如果直接啟動一堆節(jié)點,那么它們會自動組成一個elasticsearch集群桅狠,當然一個節(jié)點也可以組成一個elasticsearch集群。
Index(索引-數(shù)據(jù)庫)
索引(index)類似于關(guān)系型數(shù)據(jù)庫里的“數(shù)據(jù)庫”——它是我們存儲和索引關(guān)聯(lián)數(shù)據(jù)的地方中跌。
事實上菇篡,我們的數(shù)據(jù)被存儲和索引在分片(shards)中驱还,索引只是一個把一個或多個分片分組在一起的邏輯空間嗜暴。然而议蟆,這只是一些內(nèi)部細節(jié)——我們的程序完全不用關(guān)心分片。對于我們的程序而言咐容,文檔存儲在索引(index)中。剩下的細節(jié)由Elasticsearch關(guān)心既可路狮。
索引包含一堆有相似結(jié)構(gòu)的文檔數(shù)據(jù),比如可以有一個客戶索引奄妨,商品分類索引苹祟,訂單索引砸抛,索引有一個名稱。一個index包含很多document柳骄,一個index就代表了一類類似的或者相同的document团赏。比如說建立一個product index,商品索引丝里,里面可能就存放了所有的商品數(shù)據(jù),所有的商品document杯聚。
Type(類型-表)
在應用中抒痒,我們使用對象表示一些“事物”幌绍,例如一個用戶故响、一篇博客、一個評論彩届,或者一封郵件。每個對象都屬于一個類(class)贮聂,這個類定義了屬性或與對象關(guān)聯(lián)的數(shù)據(jù)寨辩。user類的對象可能包含姓名吓懈、性別靡狞、年齡和Email地址。
在關(guān)系型數(shù)據(jù)庫中耍攘,我們經(jīng)常將相同類的對象存儲在一個表里,因為它們有著相同的結(jié)構(gòu)扒磁。同理倔监,在Elasticsearch中,我們使用相同類型(type)的文檔表示相同的“事物”,因為他們的數(shù)據(jù)結(jié)構(gòu)也是相同的兰伤。每個類型(type)都有自己的映射(mapping)或者結(jié)構(gòu)定義,就像傳統(tǒng)數(shù)據(jù)庫表中的列一樣均澳。
每個索引里都可以有一個或多個type符衔,type是index中的一個邏輯數(shù)據(jù)分類找前,一個type下的document判族,都有相同的field,比如博客系統(tǒng)形帮,有一個索引,可以定義用戶數(shù)據(jù)type界斜,博客數(shù)據(jù)type槐臀,評論數(shù)據(jù)type锄蹂。
商品index水慨,里面存放了所有的商品數(shù)據(jù)(商品document)。但是商品分很多種類晰洒,每個種類的document的field可能不太一樣,比如說電器商品治宣,可能還包含一些諸如售后時間范圍這樣的特殊field砌滞;生鮮商品侮邀,還包含一些諸如生鮮保質(zhì)期之類的特殊field贝润。
type:日化商品type,電器商品type打掘,生鮮商品type
|- 日化商品type:product_id鹏秋,product_name亡笑,product_desc,category_id仑乌,category_name
|- 電器商品type:product_id,product_name绝骚,product_desc祠够,category_id,category_name止剖,service_period
|- 生鮮商品type:product_id落君,product_name穿香,product_desc绎速,category_id,category_name纹冤,eat_period
每一個type里面,都會包含一堆document:
{
"product_id": "1",
"product_name": "長虹電視機",
"product_desc": "4k高清",
"category_id": "3",
"category_name": "電器",
"service_period": "1年"
}
{
"product_id": "2",
"product_name": "基圍蝦",
"product_desc": "純天然雁歌,冰島產(chǎn)",
"category_id": "4",
"category_name": "生鮮",
"eat_period": "7天"
}
Document(文檔-行)
文檔是es中的最小數(shù)據(jù)單元知残,一個document可以是一條客戶數(shù)據(jù),一條商品分類數(shù)據(jù)求妹,一條訂單數(shù)據(jù),通常用JSON數(shù)據(jù)結(jié)構(gòu)表示制恍,每個index下的type中,都可以去存儲多個document吧趣。
通常耙厚,我們可以認為 對象(object) 和 文檔(document) 是等價相通的岔霸。不過,他們還是有所差別:對象(Object)是一個JSON結(jié)構(gòu)體——類似于哈希呆细、hashmap、字典或者關(guān)聯(lián)數(shù)組趴酣;對象(Object)中還可能包含其他對象(Object)坑夯。 在Elasticsearch中岖寞,文檔(document)這個術(shù)語有著特殊含義柜蜈。它特指最頂層結(jié)構(gòu)或者 根對象(root object) 序列化成的JSON數(shù)據(jù)(以唯一ID標識并存儲于Elasticsearch中)。
Field(字段-列)
Field是Elasticsearch的最小單位隶垮。一個document里面有多個field,每個field就是一個數(shù)據(jù)字段狸吞。
product document
{
"product_id": "1",
"product_name": "高露潔牙膏",
"product_desc": "高效美白",
"category_id": "2",
"category_name": "日化用品"
}
mapping(映射-約束)
ElasticSearch中的映射(Mapping)用來定義一個文檔指煎,可以定義所包含的字段以及字段的類型、分詞器及屬性等等贯要。映射可以分為動態(tài)映射和靜態(tài)映射。
(1)動態(tài)映射
我們知道字逗,在關(guān)系數(shù)據(jù)庫中,需要事先創(chuàng)建數(shù)據(jù)庫葫掉,然后在該數(shù)據(jù)庫實例下創(chuàng)建數(shù)據(jù)表跟狱,然后才能在該數(shù)據(jù)表中插入數(shù)據(jù)。而ElasticSearch中不需要事先定義映射(Mapping)驶臊,文檔寫入ElasticSearch時叼丑,會根據(jù)文檔字段自動識別類型扛门,這種機制稱之為動態(tài)映射鸠信。
示例:
- 新建索引
PUT book
{
"acknowledged": true,
"shards_acknowledged": true,
"index": "book"
}
- 查看空mapping
GET book/_mapping
{
"book": {
"mappings": {}
}
}
- 插入文檔
// it類型表示IT類書籍
PUT book/it/1{ "bookId":1, "bookName":"Java程序設(shè)計", "publishDate":"2018-01-12"}
- 再次查看映射
GET book/_mapping
{
"book": {
"mappings": {
"it": {
"properties": {
"bookId": {
"type": "long"
},
"bookName": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"publishDate": {
"type": "date"
}
}
}
}
}
}
bookId字段推測為long型星立,bookName字段推測為text類型葬凳,publishDate字段推測為date類型绰垂,這些推測都是我們可以接受的火焰。可見ElasticSearch的動態(tài)映射十分強大荐健。
在實際項目中,如果在導入數(shù)據(jù)前不能確定包含哪些字段或者不方便確定字段類型,可以使用動態(tài)映射窖逗。當向ElasticSearch寫入一個新文檔時,需要一個之前沒有的字段碎紊,會通過動態(tài)映射來推斷該字段類型。ElasticSearch動態(tài)映射規(guī)則如下音同。
JSON數(shù)據(jù) | 自動推測的類型 |
---|---|
null | 沒有字段被添加 |
true或false | boolean型 |
小數(shù) | float型 |
數(shù)字 | long型 |
日期 | date或text |
字符串 | text |
數(shù)組 | 由數(shù)組的第一個非空值 |
JSON對象 | object類型 |
(2)靜態(tài)映射
當然秃嗜,在ElasticSearch中也可以事先定義好映射权均,包含文檔的各個字段及其類型等锅锨,這種方式稱之為靜態(tài)映射。
動態(tài)映射的自動類型推測功能并不是100%正確的必指,這就需要靜態(tài)映射機制。靜態(tài)映射與關(guān)系數(shù)據(jù)庫中創(chuàng)建表語句類型塔橡,需要事先指定字段類型。相對于動態(tài)映射葛家,靜態(tài)映射可以添加更加詳細字段類型、更精準的配置信息等惦银。
示例:
- 新建映射
在6.x中創(chuàng)建的索引只允許每個索引有單一類型。任何名字都可以用于這個類型书蚪,但是只能有一個。
PUT books
{
"mappings": {
"it": {
"properties": {
"bookId": {
"type": "long"
},
"bookName": {
"type": "text"
},
"publishDate": {
"type": "date"
}
}
}
}
}
{
"acknowledged": true,
"shards_acknowledged": true,
"index": "books"
}
- 查看映射
GET books/_mapping
{
"books": {
"mappings": {
"it": {
"properties": {
"bookId": {
"type": "long"
},
"bookName": {
"type": "text"
},
"publishDate": {
"type": "date"
}
}
}
}
}
}
- 插入文件數(shù)據(jù)
PUT books/it/1{ "bookId":"1", "bookName":"Java", "publishDate":"2018-01-12"}
- 檢索
GET books/it/1
{
"_index": "books",
"_type": "it",
"_id": "1",
"_version": 1,
"found": true,
"_source": {
"bookId": "1",
"bookName": "Java",
"publishDate": "2018-01-12"
}
}
Elasticsearch與數(shù)據(jù)庫的類比
關(guān)系型數(shù)據(jù)庫(比如Mysql) | 非關(guān)系型數(shù)據(jù)庫(Elasticsearch) |
---|---|
數(shù)據(jù)庫Database | 索引Index |
表Table | 類型Type |
數(shù)據(jù)行Row | 文檔Document |
數(shù)據(jù)列Column | 字段Field |
約束 Schema | 映射Mapping |
ES支持數(shù)據(jù)類型
【注意事項】
- Keyword 類型是不會分詞的,直接根據(jù)字符串內(nèi)容建立反向索引读存,Text 類型在存入 Elasticsearch 的時候,會先分詞敬察,然后根據(jù)分詞后的內(nèi)容建立反向索引。
- 盡可能選擇范圍小的數(shù)據(jù)類型莲祸,字段的長度越短椭迎,索引和搜索的效率越高锐帜;優(yōu)先考慮使用帶縮放因子的浮點類型畜号。
ES參考文檔
英文文檔:
中文文檔:
- https://www.kaifaxueyuan.com/server/elasticsearch7/elasticsearch-java-java-rest-high-clear-scroll-api.html
- https://www.cnblogs.com/ZhuChangwu/p/11150374.html
注意:7.5.1版本和5開頭的版本有區(qū)別,具體以官方文檔為標準
引用文章:
http://www.imooc.com/article/251430?block_id=tuijian_wz