更新2015-10-15
早在2012年,我正在構建一個個人在線應用程序,並且實際上是想重新發明車輪,因爲本質上是好奇的,用於學習目的,並且提高了我的算法和架構技能。我可以使用apache lucene和其他,但正如我所說,我決定建立自己的迷你搜索引擎。如何針對倒排索引和關係數據庫優化「文本搜索」?
問題:那麼除了使用彈性搜索,lucene等可用服務之外,是否真的沒有辦法增強這種架構呢?
原來的問題
我開發一個Web應用程序,在用戶搜索特定的標題(比方說:書的x,書Y,等等。),其數據是一個關係型數據庫(MySQL的)。
我遵循的原則是,從db中獲取的每條記錄都緩存在內存中,以便應用程序對數據庫的調用較少。
我已經開發了我自己的小型搜索引擎,具有以下結構:
這是它如何工作的:
- a)用戶搜索記錄的名字
- 二)系統檢查查詢開頭的字符,檢查是否有查詢:get record。如果不存在,則使用兩種方法添加它並從數據庫中獲取所有匹配的記錄:
- 查詢中已存在查詢(這是一種歷史記錄表),從而根據ID獲取記錄(快速性能)
- 或者,否則使用Mysql LIKE %%語句來獲取記錄/ ids(然後將歷史表查詢中用戶使用的查詢與其映射到的ID一起保存)。
- >然後它將記錄和它們的ID添加到緩存以及只有ID到倒排索引映射。
- 查詢中已存在查詢(這是一種歷史記錄表),從而根據ID獲取記錄(快速性能)
- C)結果被返回到UI
系統工作正常,但是我有兩個主要問題,我無法找到(一直試圖在過去的一個很好的解決方案月):
第一個問題:
如果檢查點(b),情況沒有查詢「歷史」被發現,它使用像%%聲明:此過程變得時間當查詢數據庫(而不是一個或兩個)匹配許多紀錄耗時:
- 這將需要一段時間才能從MySQL得到記錄(這就是爲什麼我用在特定列索引)
- 然後花時間去保存查詢歷史
- 然後及時補充記錄/ IDS緩存和倒排索引映射
第二期:
該應用程序允許用戶自行添加新記錄,即立即可以使用登錄到應用程序的其他用戶。
但是爲了實現這一點,倒排索引圖和表「查詢」必須更新,以便在任何舊查詢匹配新詞時。例如,如果添加新的記錄「woodX」,仍然會將舊查詢「木材」映射到它。因此,爲了重新鉤查詢「木」這一新的記錄,這裏就是我現在所做的:
- 新紀錄「woodX」被添加到「記錄」表
- 然後我跑Like %%聲明查看哪個已存在查詢在表「queries」中是否映射到此記錄(例如「wood」),然後將此查詢與新記錄ID一起添加爲新行:[wood,new ID]。
- 然後在內存中,更新倒排索引地圖的「木」鍵的值(即列表),通過添加新的記錄id到這個列表
- >因此現在如果遠程用戶搜索「木」它會得到內存:木材和woodX
的問題這裏也是時間消耗。將所有查詢歷史記錄(在表格查詢中)與新添加的單詞匹配需要很多時間(匹配的查詢越多,時間越多)。然後內存更新也需要很多時間。
我是什麼想做來解決這個時間問題,是理想的結果返回給用戶第一,然後讓應用程序發佈一個AJAX調用與所需的數據全部實現這些UPDATE任務。但我不確定這是一種不好的做法還是一種不專業的做事方式?
因此,在過去的一個月(更多一點),我試圖想到這個架構的最佳優化/修改/更新,但我不是文件檢索領域的專家(實際上它是我有史以來第一個小型搜索引擎) 。
我希望能夠實現這種架構的任何反饋或指導我應該做什麼。
在此先感謝。
PS:
- 它使用servlet J2EE應用程序。
- 我使用MySQL的InnoDB(因此我不能使用全文搜索選項)
搜索歷史記錄(基本上是您緩存的所有內容)的範圍是由用戶定義的,還是與整個應用程序相同?即用戶2是否能夠找到緩存的對象,因爲用戶1已經查找了相同的密鑰? – theDmi
@theDmi是它是一個共享緩存(像單身人士) – shadesco