本發(fā)明屬于計(jì)算機(jī)領(lǐng)域,涉及一種搜索系統(tǒng),特別涉及一種基于mongo數(shù)據(jù)庫的搜索系統(tǒng)。
背景技術(shù):
elasticsearch是建立在lucene之上并且支持極其快速的查詢和豐富的查詢語法。作為全文搜索引擎,分析和可視化的特性使它的運(yùn)用越來越廣泛。不僅適用于數(shù)百萬的文檔的關(guān)鍵詞進(jìn)行定位,也可以作為一種輕量級的“nosql數(shù)據(jù)庫”處理json文檔。但是elasticsearch不是一個(gè)合適的數(shù)據(jù)庫引擎,對復(fù)雜的查詢和聚合并不是很強(qiáng),盡管統(tǒng)計(jì)facet可以提供一定的關(guān)于給定查詢的統(tǒng)計(jì)信息的支持。elasticsearch中的facet主要是用來支持分面的瀏覽功能。對于一些更加復(fù)雜的計(jì)算或數(shù)據(jù)庫操作,例如對數(shù)據(jù)執(zhí)行服務(wù)端的腳本,輕松地運(yùn)行mapreducejob,那么mongodb或者h(yuǎn)adoop就成為替代elasticsearch成為必要。
mongodb是一種高可擴(kuò)展性的nosql數(shù)據(jù)庫,并且有自動分片或一些性能優(yōu)化的功能。mongodb也是一種面向文檔的數(shù)據(jù)庫,以json的形式進(jìn)行數(shù)據(jù)的存儲(準(zhǔn)確地說可以稱為bson,對json進(jìn)行了一些增強(qiáng)):例如,一個(gè)native數(shù)據(jù)類型。此外,mongodb還提供了一個(gè)文本索引類型來支持全文檢索,所以我們可以看到在elasticsearch和mongodb之間的界限和不同的應(yīng)用場景。
進(jìn)一步地,mongodb超過elasticsearch的地方在于其對于服務(wù)器端js腳本的支持、聚合的管道、mapreduce的支持和cappedcollections。通過使用聚合管道來處理一個(gè)集合中的文檔,通過一個(gè)管道操作的序列來多步地對文檔進(jìn)行處理。管道操作可以生成全新的文檔并且從最終的結(jié)果中移除文檔。這是一個(gè)在檢索數(shù)據(jù)時(shí)的相當(dāng)強(qiáng)的過濾、處理和轉(zhuǎn)化數(shù)據(jù)的特點(diǎn)。mongodb也支持對一個(gè)數(shù)據(jù)collection進(jìn)行map/reducejob的執(zhí)行,使用定制的js函數(shù)進(jìn)行操作的map和reduce過程。這就保證了mongodb可以對選定的數(shù)據(jù)執(zhí)行任意類型的計(jì)算或者轉(zhuǎn)換的終極的靈活性。
mongodb另一個(gè)極其強(qiáng)大的特性稱之為“cappedcollections”。使用這個(gè)特性,用戶可以定義一個(gè)collection的最大size——然后這個(gè)collection可以被盲寫,并且會roll-over必須的數(shù)據(jù)來獲取log和其他供分析的流數(shù)據(jù)。
綜上,elasticsearch可以完成關(guān)鍵字和簡單的分析;而mongodb更加適合文檔查詢,和更加復(fù)雜的分析處理;hadoop雖然提供了最為廣泛的工具和靈活性來,但部署復(fù)雜、硬件要求高,對于輕量級(pb)的情況下無疑造成了資源的浪費(fèi)。
技術(shù)實(shí)現(xiàn)要素:
為解決elasticsearch不能滿足復(fù)雜的分析,和mongodb不適用于關(guān)鍵字和簡單的分析,本發(fā)明提供了一種基于mongo數(shù)據(jù)庫的搜索系統(tǒng),融合了兩者的優(yōu)點(diǎn),解決了關(guān)鍵字和簡單的分析、復(fù)雜的后臺數(shù)據(jù)分析的問題。
為實(shí)現(xiàn)上述目的,本發(fā)明提供了一種基于mongo數(shù)據(jù)庫的搜索系統(tǒng),包括elasticsearch集群、mongo數(shù)據(jù)庫、橋接器;
所述mongo數(shù)據(jù)庫用于存儲elasticsearch集群索引請求、查詢請求的數(shù)據(jù)源并根據(jù)規(guī)則將數(shù)據(jù)返回給elasticsearch集群;
所述elasticsearch集群用于接收和處理用戶的搜索和/或查詢請求,通過訪問mongo數(shù)據(jù)庫將搜索和/或查詢的結(jié)果返回給用戶;
所述橋接器分別與mongo副本集、elasticsearch集群連接,用于實(shí)時(shí)將mongo數(shù)據(jù)庫的操作轉(zhuǎn)為elasticsearch操作,并將操作下的數(shù)據(jù)文檔更新到elasticsearch集群中。
在本發(fā)明的一個(gè)實(shí)施例中,所述mongo數(shù)據(jù)庫為副本集集群。
在本發(fā)明的一個(gè)實(shí)施例中,所述elasticsearch集群包括索引模塊、查詢模塊、映射模塊,所述索引模塊包括mapping、setting,所述setting控制索引行為,包括自定義過濾器,同義詞,停用詞以及對應(yīng)索引的集群配置;所述mapping定義域的關(guān)系、存儲類型;
所述查詢模塊利用elasticsearch提供restful風(fēng)格接口對elasticsearch進(jìn)行操作。
進(jìn)一步地,所述索引模塊采用動態(tài)模板對非關(guān)鍵字字段生成索引映射,對關(guān)鍵字段逐個(gè)定義映射關(guān)系。
進(jìn)一步地,所述索引模塊在導(dǎo)入數(shù)據(jù)之前使用bulk批量索引,通過設(shè)置每次bulk的大小和請求數(shù)量,將分片的副本數(shù)調(diào)整為0。
在本發(fā)明的一個(gè)實(shí)施例中,所述橋接器包括mongo-connector和elastic2-doc-manager,所述mongo-connector將mongo數(shù)據(jù)庫的操作實(shí)時(shí)轉(zhuǎn)換為elasticsearch操作,然后發(fā)送給elastic2-doc-manager去執(zhí)行,將數(shù)據(jù)更新到所述elasticsearch集群中。
進(jìn)一步地,所述mongo-connector在mongo數(shù)據(jù)庫開啟副本集模式之后,會在主節(jié)點(diǎn)中加入一個(gè)oplog文件,所述oplog文件記錄了mongo數(shù)據(jù)庫開啟副本集模式之后的對數(shù)據(jù)的所有操作及所有操作的時(shí)間戳。
進(jìn)一步地,所述elastic2-doc-manager將elasticsearch操作的請求結(jié)構(gòu)體加入mongo數(shù)據(jù)庫中缺乏的以鍵值對形指明的關(guān)系依賴。
更進(jìn)一步地,所述elastic2-doc-manager根據(jù)不同的elasticsearch關(guān)系修改請求體函數(shù)。
更進(jìn)一步地,所述請求體函數(shù)為upsert函數(shù)。
本發(fā)明還提供了實(shí)現(xiàn)上述系統(tǒng)的方法,具體步驟如下:
s1:搭建mongo副本集,包括相關(guān)的服務(wù)開啟和權(quán)限設(shè)置;
s2:搭建elasticsearch集群,包括節(jié)點(diǎn)角色確定、節(jié)點(diǎn)發(fā)現(xiàn)方式、索引分片數(shù)目確定;
s3:分析數(shù)據(jù)庫結(jié)構(gòu),確定有檢索需求的文檔;
s4:設(shè)計(jì)elasticsearch索引結(jié)構(gòu),包括文檔關(guān)系、分詞方式、字段存儲方式和類型、索引setting的設(shè)計(jì);
s5:從mongo數(shù)據(jù)庫首次導(dǎo)入數(shù)據(jù)到elasticsearch,包括java編寫、spring管理bean,spring增量更新;
s6:編寫前段交互業(yè)務(wù)及接口,包括java編寫、spring管理bean,spring控制接口。
本發(fā)明的有益效果是:
1.實(shí)現(xiàn)elasticsearch和mongo數(shù)據(jù)庫的融合,實(shí)現(xiàn)關(guān)鍵字和簡單的分析,以及文檔搜索,部署快速簡單,使用方便。
2.利用時(shí)間戳的監(jiān)視,實(shí)現(xiàn)elasticsearch的增量索引,減小了服務(wù)器的帶寬負(fù)擔(dān),保證了數(shù)據(jù)的完整性。
3.針對elasticsearch請求體的函數(shù)可根據(jù)實(shí)際系統(tǒng)的需求而進(jìn)行調(diào)整,提高了系統(tǒng)的靈活性。
附圖說明
圖1是本發(fā)明的基本原理圖;
圖2是本發(fā)明的橋接器的結(jié)構(gòu)示意圖;
圖3是本發(fā)明的elasticsearch框架原理圖;
圖4是本發(fā)明的mongo數(shù)據(jù)庫副本集原理圖;
圖5是本發(fā)明的oplog文件結(jié)構(gòu)示意圖;
圖6是本發(fā)明的橋接器工作流程示意圖;
圖7是本發(fā)明的elasticsearch的upsert方法的請求結(jié)構(gòu)體示意圖;
圖8是本發(fā)明的橋接器未修改結(jié)果返回示意圖;
圖9是本發(fā)明的橋接器修改后的結(jié)果返回示意圖;
圖10是本發(fā)明的成功開啟橋接器的elasticsearch集群效果圖;
圖11是本發(fā)明的開啟增量索引的查詢結(jié)果示意圖;
圖12是本發(fā)明的elasticsearch的bulk批量操作的設(shè)置示意圖;
圖13是本發(fā)明的搜索系統(tǒng)的實(shí)現(xiàn)流程圖。
具體實(shí)施方式
為了更好的理解本發(fā)明所提出的技術(shù)方案,下面結(jié)合附圖和具體的實(shí)施例對本發(fā)明作進(jìn)一步闡述。
如圖1至圖4所示,本發(fā)明提供了一種基于mongo數(shù)據(jù)庫的搜索系統(tǒng),包括elasticsearch集群、mongo數(shù)據(jù)庫、橋接器;所述mongo數(shù)據(jù)庫用于存儲elasticsearch集群索引請求、查詢請求的數(shù)據(jù)源并根據(jù)規(guī)則將數(shù)據(jù)返回給elasticsearch集群;
所述elasticsearch集群用于接收和處理用戶的搜索和/或查詢請求,通過訪問mongo數(shù)據(jù)庫將搜索和/或查詢的結(jié)果返回給用戶;
所述橋接器分別與mongo副本集、elasticsearch集群連接,用于實(shí)時(shí)將mongo數(shù)據(jù)庫的操作轉(zhuǎn)為elasticsearch操作,并更新到elasticsearch中。
在本發(fā)明的一個(gè)實(shí)施例中,使用mongo官方原生api從遠(yuǎn)程mongo數(shù)據(jù)庫讀取有搜索需求的所有文檔,利用elasticsearch官方j(luò)avaapi在elasticsearch集群中對所有文檔建立索引,前端接口使用springmvc的controller結(jié)合javascript實(shí)現(xiàn),elasticsearch、springmvc、mongo操作使用spring自動管理beans實(shí)現(xiàn)。
為實(shí)現(xiàn)elasticsearch增量索引,在本發(fā)明的一個(gè)實(shí)施例中,所述mongo數(shù)據(jù)庫為副本集集群。其中primary為主節(jié)點(diǎn),負(fù)責(zé)與外部的交互讀寫;secondary為從節(jié)點(diǎn),負(fù)責(zé)外部的讀,但是不負(fù)責(zé)寫,分擔(dān)主節(jié)點(diǎn)壓力;arbiter則為仲裁結(jié)點(diǎn),不用存儲數(shù)據(jù),負(fù)責(zé)在主節(jié)點(diǎn)出現(xiàn)故障時(shí)從余下正常從節(jié)點(diǎn)中選舉新的主節(jié)點(diǎn),確保副本集(復(fù)制集)正常運(yùn)行。
在本發(fā)明的一個(gè)實(shí)施例中,所述elasticsearch集群包括索引模塊、查詢模塊、映射模塊,所述索引模塊包括mapping、setting,所述setting控制索引行為,包括自定義過濾器,同義詞,停用詞以及對應(yīng)索引的集群配置;所述mapping定義域的關(guān)系、存儲類型;
所述查詢模塊利用elasticsearch提供restful風(fēng)格接口對elasticsearch進(jìn)行操作。setting使用自定義分詞器,使用中文分詞器ik來作為主要分詞器。
在本發(fā)明的一個(gè)實(shí)施例中,對elasticsearch的索引模塊進(jìn)行改進(jìn):
a)為防止索引過大占用磁盤過多,禁掉_all字段(索引的各個(gè)field字符串拼成的字段),因?yàn)樵撟侄卧斐蓴?shù)據(jù)冗余,但由此需要在查詢時(shí)指定查詢fields(在es5。x_all字段被移除,查詢會根據(jù)字段類型查找相應(yīng)fields)。
b)為應(yīng)對數(shù)據(jù)庫結(jié)構(gòu)變化,索引的mapping使用dynamic_template(動態(tài)模板)設(shè)計(jì),結(jié)合es動態(tài)mapping特性可以應(yīng)對數(shù)據(jù)庫加入某些待檢索但結(jié)構(gòu)簡單的字段引起的所有結(jié)構(gòu)變化。
c)索引使用別名,通過更改別名使用的所有結(jié)構(gòu)來做到在運(yùn)行過程中平滑的改變索引結(jié)構(gòu)。對于評論這種可能分析數(shù)據(jù)需要檢索但是不要求展示的字段,可以在索引下的_source字段中排除,使用store設(shè)置為yes來單獨(dú)存儲。
d)從數(shù)據(jù)庫索引大量文檔前關(guān)閉索引的刷新或增大刷新時(shí)間,另外使用bulk批量索引,合理設(shè)置每次bulk的大小和請求數(shù)量,分片的副本數(shù)調(diào)整為0,待數(shù)據(jù)導(dǎo)入完成,再調(diào)回之前配置,可以加快文檔導(dǎo)入速度。具體的設(shè)置參考圖12。
在本發(fā)明的一個(gè)實(shí)施例中,elasticsearch集群配置為:1)cluster中的node角色明確分開,masternode不存放數(shù)據(jù),只負(fù)責(zé)維護(hù)集群狀態(tài),而datanode則只負(fù)責(zé)讀數(shù)據(jù),clientnode負(fù)責(zé)寫數(shù)據(jù),可以做到負(fù)載均衡。2)使用unicast方式發(fā)現(xiàn)新加入集群的節(jié)點(diǎn),不使用multicast,保證安全性和高效性。
在本發(fā)明的一個(gè)實(shí)施例中,查詢模塊的改進(jìn):
a)為了保證查詢準(zhǔn)確性,操作中需要對各個(gè)字段設(shè)置boost值,為保證業(yè)務(wù)靈活性,不選擇在索引時(shí)設(shè)置boost,在查詢時(shí)設(shè)置能保證應(yīng)對不同需求。
b)查詢不使用絕對匹配的原則,比如must選項(xiàng),term匹配等等盡量少使用,而采用模糊匹配,結(jié)合should,should_not等選項(xiàng)。
進(jìn)一步地,所述索引模塊采用動態(tài)模板對非關(guān)鍵字字段生成索引映射,對關(guān)鍵字段逐個(gè)定義映射關(guān)系。例如教學(xué)視頻搜索中的課程、課時(shí)、視頻為關(guān)鍵字段,課程信息、課程分類等屬于非關(guān)鍵字段。
在本發(fā)明的一個(gè)實(shí)施例中,所述橋接器包括mongo-connector和elastic2-doc-manager,所述mongo-connector將mongo數(shù)據(jù)庫的操作實(shí)時(shí)轉(zhuǎn)換為elasticsearch操作,然后發(fā)送給elastic2-doc-manager去執(zhí)行,將數(shù)據(jù)更新到所述elasticsearch集群中。其中mongo-connector和elastic2-doc-manager是使用python編寫的第三方插件。
如圖5所示,所述mongo-connector在mongo數(shù)據(jù)庫開啟副本集模式之后,會在主節(jié)點(diǎn)中加入一個(gè)oplog文件,所述oplog文件記錄了mongo數(shù)據(jù)庫開啟副本集模式之后的對數(shù)據(jù)的所有操作及所有操作的時(shí)間戳。其中:
op,包括如下選項(xiàng):"i":insert(插入);"u":update(上傳);"d":delete(刪除);"c":dbcmd(命令行);
ts:代表8字節(jié)的時(shí)間戳,由4字節(jié)unixtimestamp+4字節(jié)自增計(jì)數(shù)表示。
o:操作所對應(yīng)的document,即當(dāng)前操作的內(nèi)容(比如更新操作時(shí)要更新的的字段和值)
如圖6至圖7所示,在本發(fā)明的一個(gè)實(shí)施例中,所述elastic2-doc-manager將elasticsearch操作的請求結(jié)構(gòu)體加入mongo數(shù)據(jù)庫中缺乏的以鍵值對形式指明的關(guān)系依賴。
進(jìn)一步地,如圖7所示所述elastic2-doc-manager根據(jù)不同的elasticsearch(以下簡稱es)關(guān)系修改請求體函數(shù)。具體的做法為:mongo-connector插件可以通過時(shí)間戳拿到對應(yīng)操作,然后轉(zhuǎn)換為es的操作。而es的請求結(jié)構(gòu)體是json格式,es中許多關(guān)系需要在導(dǎo)入數(shù)據(jù)時(shí),在該結(jié)構(gòu)體中以鍵值對形式指明的關(guān)系依賴,比如parent-child關(guān)系,需要在請求體中加入_parent:xxxx的鍵值對,否則該請求不能執(zhí)行。然而mongo-connector在轉(zhuǎn)換操作過程中并沒有對這些關(guān)系的處理過程。
更進(jìn)一步地,所述請求體函數(shù)為upsert函數(shù)。
如圖7所示,es(elasticsearch)的請求結(jié)構(gòu)體初始狀態(tài)。針對不同的es關(guān)系編寫修改該請求體的函數(shù),在該函數(shù)中調(diào)用,編寫為使用參數(shù)形式在啟動該插件時(shí)指定關(guān)系依賴情況,比如當(dāng)前mongo-connector啟動時(shí)命令通常為:
mongo-connecto-mlocalhost:27017-tlocalhost:9200-delastic2_doc_manager;
-m:mongo數(shù)據(jù)庫地址;
-t:es地址;
-d:指定由elastic2_doc_manager來運(yùn)行轉(zhuǎn)換后的請求;
然后可以加入其他參數(shù)描述es關(guān)系的,比如-p:indexname。typenameparent-child關(guān)系參照某個(gè)index下某個(gè)type;
-r:indexname。typename。fieldnamerouting值參照某個(gè)具體域的值;
然后在upsert函數(shù)中根據(jù)此設(shè)置加入對應(yīng)鍵值對。在發(fā)明的一個(gè)實(shí)施例中,upsert函數(shù)中加入的部分代碼示例如下:
代碼中course_,lesson,video是以課程搜索舉例,可根據(jù)系統(tǒng)涉及不同的業(yè)務(wù)關(guān)系進(jìn)行調(diào)整,例如將course、lesson替換為對應(yīng)于購物網(wǎng)站的某個(gè)商品分類product\clothes,video修改為產(chǎn)品的信息size。
如圖8所示,在有parent-child關(guān)系和routing值時(shí),修改前的請求體函數(shù)在執(zhí)行elasticsearch操作時(shí),返回的結(jié)果表明routing不能為空,即請求體中必須要有_routing:xxxx鍵值對。
如圖9所示,修改后的請求體函數(shù)均正常返回index、type、id、version等鍵值。
如圖10至12所示,開啟成功增量索引后的elasticsearch集群查詢效果圖,查詢5個(gè)分片,4個(gè)命中,耗時(shí)0.047秒。
由此可知改進(jìn)mongo-connector后,可增大es導(dǎo)入數(shù)據(jù)時(shí)的靈活性,避免了實(shí)時(shí)導(dǎo)入時(shí)放棄elasticsearch的關(guān)系,一定程度上加快系統(tǒng)的部署進(jìn)度,同時(shí)也保證了數(shù)據(jù)完整性。
如圖13所示,本發(fā)明還提供上述系統(tǒng)的實(shí)施方法,搭建mongo副本集,包括相關(guān)的服務(wù)開啟和權(quán)限設(shè)置;
搭建elasticsearch集群,包括節(jié)點(diǎn)角色確定、節(jié)點(diǎn)發(fā)現(xiàn)方式、索引分片數(shù)目確定;
分析數(shù)據(jù)庫結(jié)構(gòu),確定有檢索需求的文檔;
設(shè)計(jì)elasticsearch索引結(jié)構(gòu),包括文檔關(guān)系、分詞方式、字段存儲方式和類型、索引setting的設(shè)計(jì);
從mongo數(shù)據(jù)庫首次導(dǎo)入數(shù)據(jù)到elasticsearch,包括java編寫、spring管理bean,spring處理請求;另外基于java針對簡單業(yè)務(wù)可直接使用es原生api+springboot輕量級框架,處理數(shù)據(jù)傳輸、請求處理可另外結(jié)合struts2。
編寫前段交互業(yè)務(wù)及接口,包括java編寫、spring管理bean,springmvc控制接口。
根據(jù)上述說明書的揭示和教導(dǎo),本發(fā)明所屬領(lǐng)域的技術(shù)人員還可以對上述實(shí)施方式的相關(guān)模塊和軟件架構(gòu)做適應(yīng)性變更和修改。因此,本發(fā)明并不局限于上面揭示和描述的具體實(shí)施方式,對發(fā)明的一些修改和變更也應(yīng)當(dāng)落入本發(fā)明的權(quán)利要求的保護(hù)范圍內(nèi)。此外,盡管本說明書中使用了一些特定的術(shù)語,但這些術(shù)語只是為了方便說明,并不對本發(fā)明構(gòu)成任何限制。