溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

全文檢索-Lucene

發(fā)布時(shí)間:2020-04-04 06:28:49 來源:網(wǎng)絡(luò) 閱讀:777 作者:yayaAA 欄目:數(shù)據(jù)庫

01.說明-全文檢索(概念)

數(shù)據(jù)量大,要求高的時(shí)候,數(shù)據(jù)庫內(nèi)容很多,數(shù)據(jù)庫搜索的時(shí)候?qū)?shù)據(jù)庫服務(wù)器壓力大的時(shí)候,請(qǐng)用全文檢索-Lucene框架

 

搜索的數(shù)據(jù)是什么?

文本(important

多媒體

 

搜索的方式是什么?

不處理語義

 

搜索含有指定詞匯的文章

 

應(yīng)用范圍?

網(wǎng)頁搜索,貼吧搜索,文檔搜索等

 

全文檢索的要求?

搜索速度要快

結(jié)果要準(zhǔn)確

搜出多個(gè)結(jié)果的時(shí)候,把最匹配的結(jié)果放在前面,相關(guān)度排序

不區(qū)分大小寫

 

02-Lucene的作用說明

lucene.apache.org

apache提供了tomcat/struts/beanutils/dbUtils/..

 

Lucene實(shí)現(xiàn)全文檢索的原理

在大量數(shù)據(jù)之中,Lucene如何實(shí)現(xiàn)快速檢索功能呢?

百度搜索---用戶請(qǐng)求發(fā)給百度服務(wù)器---返回結(jié)果

很多爬蟲從互聯(lián)網(wǎng)中抓了數(shù)據(jù)組織特定(快速搜索)格式放到百度服務(wù)器中的索引庫

│  

Lucene管理索引庫,對(duì)外提供搜索功能

全文檢索-Lucene

03-LuceneAPI與數(shù)據(jù)結(jié)構(gòu)簡(jiǎn)介說明

索引庫存放一堆二進(jìn)制數(shù)據(jù),可以吧索引庫理解為數(shù)據(jù)庫

 

如何建立索引庫的目錄?

網(wǎng)頁,文件,在java中表現(xiàn)的都是一個(gè)對(duì)象,普通javabean,用Map<String, Object>表示一個(gè)javabean里面的所有信息,比如Map<name,value>

全文檢索-Lucene 

04-準(zhǔn)備Lucene的開發(fā)環(huán)境+HelloWorld(建立索引)

核心包lucene-core-3.0.1.jar

特定功能包

分詞器 lucene-analyzers-3.0.1.jar

高亮關(guān)鍵字 lucene-highlighter-3.0.1.jar

高亮功能依賴的包 lucene-memory-3.0.1.jar

 

快速操作模式 shift + Alt +A

 

06-索引庫的內(nèi)部結(jié)構(gòu)

索引庫有兩個(gè)區(qū)

1.目錄區(qū)-分詞器劃分關(guān)鍵字,存儲(chǔ)(關(guān)鍵字與n個(gè)文章)對(duì)應(yīng)關(guān)系

2.數(shù)據(jù)區(qū)-存儲(chǔ)document

doc.add(new Field("id", idStr, Store.YES, Index.ANALYZED));

doc.add(new Field("title", article.getTitle(), Store.YES, Index.ANALYZED));

doc.add(new Field("content", article.getContent(), Store.NO, Index.ANALYZED));

Store參數(shù)

用于指定某Field的原始值是否存到數(shù)據(jù)庫中

YES - 存儲(chǔ),取出的Document中就有這個(gè)字段的值

NO - 不存儲(chǔ),取出的Document中就沒有這個(gè)字段的值

 

Index參數(shù)

用于指定是否把某個(gè)Field中的文本值更新到目錄區(qū)中

NO - 不更新到目錄區(qū)中,不能按此字段搜索

ANALYZED - 先把字段文本值分詞處理,把分詞后的結(jié)果更新到目錄中

NOT_ANALYZED - 不分詞,直接把Field的文本值當(dāng)作一個(gè)詞更新到目錄中,應(yīng)用場(chǎng)景:作者、日期、數(shù)字、url、文件地址

 

Store

Index

應(yīng)用場(chǎng)景

YES

ANALYZED

能搜索 能顯示

YES

NO

不按一個(gè)字段搜索,但是顯示的時(shí)候,會(huì)顯示出這個(gè)字段。比如作者,不按作者搜索,但是顯示文章的時(shí)候會(huì)顯示作者。將一些數(shù)據(jù)存儲(chǔ)在索引庫里,可以直接拿出來用,不用再向數(shù)據(jù)庫要數(shù)據(jù)了,一次查詢顯示所有數(shù)據(jù),效率高,比如百度快照。如果這個(gè)數(shù)據(jù)特別大,那就考慮不把內(nèi)容存到索引庫里面了。

NO

ANALYZED

能按這個(gè)字段搜索,能找到這個(gè)字段對(duì)應(yīng)的數(shù)據(jù)編號(hào),但是不顯示這個(gè)字段內(nèi)容。比如電子書,能按照內(nèi)容搜索,但是在結(jié)果頁面不顯示電子數(shù)內(nèi)容,只顯示電子書標(biāo)題、作者

NO

NOT_ANALYZED

不允許

 

07-建立索引與搜索的過程分析

1.建立索引 - 增刪改索引庫

1.Article轉(zhuǎn)為Document

Document doc = new Document();

doc.add(new Field("id", idStr, Store.YES, Index.ANALYZED));


2.添加到索引庫中

IndexWriter indexWriter =

new IndexWriter(directory, analyzer,  MaxFieldLength.UNLIMITED);

indexWriter.addDocument(doc);

做兩件事情(1)Document存到數(shù)據(jù)區(qū)中,這個(gè)時(shí)候會(huì)自動(dòng)分配一個(gè)內(nèi)部編號(hào)

(2)把一個(gè)field值(分詞或者不分詞)更新到目錄中。

 

2.搜索

搜索過程

1,把查詢字符串轉(zhuǎn)為Query對(duì)象(默認(rèn)只從title中查詢)

QueryParser queryParser = new QueryParser(Version.LUCENE_30, "title", analyzer);

Query query = queryParser.parse(queryString);

2,執(zhí)行查詢,得到中間結(jié)果 搜索目錄

IndexSearcher indexSearcher = new IndexSearcher(directory); // 指定所用的索引庫

TopDocs topDocs = indexSearcher.search(query, 100); // 最多返回前n條結(jié)果

int count = topDocs.totalHits;//關(guān)聯(lián)總條數(shù)

ScoreDoc[] scoreDocs = topDocs.scoreDocs;

 

 3,處理結(jié)果 根據(jù)docId取出真正的Document數(shù)據(jù)

 

搜索的時(shí)候 也要分詞,分成關(guān)鍵字去匹配目錄里面的關(guān)鍵字

 

分詞器

 分詞規(guī)則

建立索引 搜索 都使用同一個(gè)分詞規(guī)則

 

MaxFieldLength

有限制10000 default

無限制 max

建立索引目錄的時(shí)候,只處理字段前多少個(gè)詞

 

08-Web應(yīng)用程序中使用Lucene的方案

全文檢索-Lucene 

web應(yīng)用增刪改數(shù)據(jù)庫和索引庫會(huì)引發(fā)哪些問題?

數(shù)據(jù)庫和索引庫都有文章的信息,1.浪費(fèi)存儲(chǔ)空間2.狀態(tài)同步問題

1.是否浪費(fèi)?

索引庫存放數(shù)據(jù)的原則:能被搜索的數(shù)據(jù),比如數(shù)據(jù)庫里有作者表,文章表,索引庫只存了文章表,根據(jù)作者搜索,可以搜索出作者寫的文章,而搜索不出作者的具體信息。重復(fù)的數(shù)據(jù)只是需要被搜索出來的數(shù)據(jù)。

一次搜索顯示所有數(shù)據(jù),減輕數(shù)據(jù)庫壓力。

實(shí)現(xiàn)全文搜索必須要索引庫,為了不存儲(chǔ)重復(fù)信息,是否能取消數(shù)據(jù)庫,把數(shù)據(jù)全部存到索引庫中?

不行!數(shù)據(jù)庫的一些功能,索引庫無法實(shí)現(xiàn),比如事務(wù)管理。

 

2.保證索引庫的狀態(tài)與數(shù)據(jù)源的狀態(tài)一致的方案:

(1)方案一:當(dāng)對(duì)數(shù)據(jù)庫做增刪改的操作時(shí),就同時(shí)對(duì)索引庫也做增刪改的操作會(huì)出現(xiàn)什么問題?在一個(gè)別人已經(jīng)存在的一個(gè)程序上,不讓你修改他們的程序,但是我要增加一個(gè)搜索功能,怎么辦?比如百度去對(duì)別人網(wǎng)頁的數(shù)據(jù)做組織成一個(gè)搜索。

(2)方案二:自己不能控制數(shù)據(jù)源的時(shí)候,定時(shí)從數(shù)據(jù)源中抓取數(shù)據(jù) -- 爬蟲的概念。定時(shí)重建索引庫,(或者定時(shí)與數(shù)據(jù)源做同步的操作),有時(shí)候做同步操作還沒有重建索引庫快呢,除非索引庫忒別大。忒別大的時(shí)候就是利用爬蟲分析網(wǎng)絡(luò)上的網(wǎng)頁是否有最新數(shù)據(jù),比如MD5摘要一下網(wǎng)頁中的內(nèi)容,(MD5摘要的內(nèi)容是不可逆的),兩個(gè)不同字符串做MD5摘要是不同,對(duì)比MD5摘要,不一樣就更新索引庫,幾百萬的數(shù)據(jù)重建是比較快的。

 

垂直搜索:對(duì)專業(yè)的事情有更細(xì)致的分析,比如淘寶搜索商品,能根據(jù)價(jià)格搜索特點(diǎn)商品。

 

根據(jù)數(shù)據(jù)源的不同,采用不同方案

1.數(shù)據(jù)源是數(shù)據(jù)庫  使用方案一或者方案二

2.數(shù)據(jù)源是網(wǎng)頁  使用方案二,流行垂直搜索

3.數(shù)據(jù)源是文件  采用JNI技術(shù):在java里面調(diào)用C或者C++程序,及時(shí)獲取操作系統(tǒng)的信息。使用方案二。

 

eg:利用struts2做 貼吧的增刪改查

ArticleAction{

add() {

form-->article; dao.save(article);..//保存到數(shù)據(jù)庫

indexDao.save(article)//保存到索引庫

}

delete() {

 id = getparam(id); dao.delete(id);..//從數(shù)據(jù)庫里刪除

//從索引庫中刪除

}

modify() {

article= getById(id); form-->articel; dao.update(article);//更新到數(shù)據(jù)庫

//更新到索引庫

 }

}

 

對(duì)索引庫的增刪改查

IndexDao{

save(article);

delete(id);

update(article);

search(str)

...

}

 


09-實(shí)現(xiàn)IndexDao(一)

article id也要存到索引庫里,必須不分詞的存入,這是唯一標(biāo)識(shí)符,可以準(zhǔn)確鎖定article,比如可以根據(jù)id查找刪除索引庫里article。

 

int 類型轉(zhuǎn)化為string類型使用lucene里面的方法,存放的int類型的2進(jìn)制類型。直接用toString會(huì)將一個(gè)4字節(jié)的數(shù)據(jù)變成一個(gè)十幾個(gè)字節(jié)的數(shù)據(jù),浪費(fèi)空間,不好排序。

 

Ctrl + T 查看繼承關(guān)系

測(cè)試

 

12-實(shí)現(xiàn)IndexDao(四)-管理單例的IndexWriter

初始化IndexWriter 如果沒有關(guān)閉,正在被使用,可能內(nèi)存上的緩存就沒有刷新到硬盤上面,沒有釋放資源,web應(yīng)用程序需要反正application監(jiān)聽器里面,在應(yīng)用程序啟動(dòng)時(shí)創(chuàng)建indexwriter對(duì)象,應(yīng)用程序退出之前關(guān)閉indexwriter對(duì)象。java程序,虛擬機(jī)退出之前關(guān)閉eindexWriter對(duì)象。指定一段代碼,在jvm退出之前執(zhí)行。

 

13-優(yōu)化索引庫:合并文件的方法

 

indexDir文件夾里面很多文件,有的已經(jīng)被標(biāo)記為刪除文件,為什么不直接刪除,而是標(biāo)記呢,這是應(yīng)為這個(gè)文件夾很大,頻繁修改增刪這個(gè)文件夾可能帶來效率低問題,什么時(shí)候才刪除這些標(biāo)記文件呢,lucene不忙的時(shí)候,才進(jìn)行合并或者刪除。這些被標(biāo)記刪除的文件怎么可以不被查出來呢?先查出所有數(shù)據(jù),再過濾掉del文件。優(yōu)化之后,就沒有了del文件了==合并文件,幾個(gè)小文件合并成一個(gè)大文件,減少io操作。

優(yōu)化 就是 合并文件,合并幾個(gè)小文件成一個(gè)大文件

什么時(shí)候合并文件呢

批量操作,每天重新創(chuàng)建索引庫,抓了更多文件之后合并成一個(gè)大文件放入索引庫里面,當(dāng)擴(kuò)展名相同的文件達(dá)到一定數(shù)量之后,默認(rèn)10條,最小2條,再合并==自動(dòng)優(yōu)化,

  @Test

public void test() throws Exception {

LuceneUtils.getIndexWriter().optimize();

}

 

// 自動(dòng)合并文件

@Test

public void testAuto() throws Exception {

// 配置當(dāng)小文件的數(shù)量達(dá)到多少個(gè)后就自動(dòng)合并為一個(gè)大文件,默認(rèn)為10,最小為2.

LuceneUtils.getIndexWriter().setMergeFactor(5);

 

// 建立索引

Article article = new Article();

article.setId(1);

article.setTitle("準(zhǔn)備Lucene的開發(fā)環(huán)境");

article.setContent("如果信息檢索系統(tǒng)在用戶發(fā)出了檢索請(qǐng)求后再去互聯(lián)網(wǎng)上找答案,根本無法在有限的時(shí)間內(nèi)返回結(jié)果。");

new ArticleIndexDao().save(article);

}

 

07-網(wǎng)頁爬蟲的實(shí)現(xiàn)方案1

爬蟲:功能,抓網(wǎng)頁。

 

把一個(gè)網(wǎng)站上面所有頁面下載下來?

 

方案:

0.初始條件:首頁

1.下載網(wǎng)頁得到網(wǎng)頁的內(nèi)容    

2.獲取其中所有超鏈接     

3.去掉已經(jīng)下載過的鏈接和棧外的鏈接     

4.循環(huán)處理每一個(gè)有效的超鏈接  回到 1 沒新的鏈接出現(xiàn)就停止循環(huán)

 

技術(shù):

如何下載一個(gè)網(wǎng)站的URL  -   UrlConnectionSocket

Http協(xié)議 發(fā)送請(qǐng)求 響應(yīng)實(shí)體內(nèi)容

1.下載網(wǎng)頁

public static String downLoad(String urlString){

URL url = new URL(urlString);

URLConnection conn = url.openConnection();

InputStream in = conn.getInputStream();

//in 流中的數(shù)據(jù)就是網(wǎng)頁內(nèi)容

 

2.獲取所有的超鏈接

Dom + XPath

 

3.去掉已經(jīng)下載過的鏈接和棧外的鏈接     

把下載過的鏈接全部放到數(shù)據(jù)庫里面,或者一個(gè)集合里面,新的鏈接和集合中的鏈接進(jìn)行比較,看是否包含。

 

如果要做到更好一點(diǎn):出現(xiàn)網(wǎng)絡(luò)問題,好多個(gè)線程去訪問,總有幾個(gè)線程訪問不了,可以進(jìn)行3次請(qǐng)求鏈接。

 

全文檢索-Lucene 

多個(gè)線程不斷的從任務(wù)隊(duì)列里面拿任務(wù)

任務(wù)隊(duì)列的(需要完成的任務(wù))放到數(shù)據(jù)庫里面,停電也沒有關(guān)系。多線程從數(shù)據(jù)庫里查詢和刪除任務(wù)。隊(duì)列形式解決了遞歸的內(nèi)存溢出,停電無斷點(diǎn),不能使用多線程的問題。

java里面用LinkedList表示隊(duì)列

addFirst()   removeLast()

addLast()   removeFirst()   

 

使用多種模式:使用架構(gòu),mvc,繼承

類變多了,關(guān)系變復(fù)雜了

1.適用更復(fù)雜,要求嚴(yán)格的情況

2.代碼可讀性好

3.結(jié)構(gòu)合理,方便修改

4.方便擴(kuò)展,可維護(hù)性強(qiáng)

 

 

 


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI