欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
Lucene的學(xué)習

通過(guò)這幾天的看書(shū)和學(xué)習,對 Lucene 有了更進(jìn)一步的認識,所以總結一下這些天的學(xué)習成果把 Lucene 的學(xué)習心得也學(xué)出來(lái)。

1          Lucene 的認識

提到 Lucene 很多人都知道這個(gè)開(kāi)源的搜索工具,其魅力也是很大的。它讓我們對搜索引擎的認識不在那么神秘,也不會(huì )在覺(jué)得百度和 google 的技術(shù)多么的高深沒(méi)測,其實(shí)其原理都是一樣的,只是他們要做的更好,走的更遠罷了。

Lucene 可以對任何的數據做索引和搜索,說(shuō)這樣的話(huà)其實(shí)不過(guò)分,真的就是這樣,只要你能處理好這些數據,交給 Lucene 去建立索引它都可以幫你把這些數據給檢索出來(lái),是不是很好玩了。真正好玩的地方還在后面呢。

2          Lucene 的學(xué)習

前面已經(jīng)對 Lucene 有了一些了解,現在我們想象它怎么去搜索這些數據呢,如果知道倒排索引,你就知道了,其實(shí) lucene 檢索的是它自己建立的索引,從索引中的到數據的指針,從而得到數據。其實(shí)就這么簡(jiǎn)單。

提到索引,現在的索引技術(shù)中有:倒排索引、后綴數組和簽名文件這三種,其中后綴數組這種技術(shù)雖然檢索速度也很快,但是它的數據結構構造和維護都是相當麻煩的所以不可取了。我也懶得去看了。至于簽名文件嘛,那是 80 年代的玩意了,現在已經(jīng)過(guò)時(shí)了?,F在可是倒排索引的天下??!相信百度和 google 都是這種技術(shù)。

3          索引的建立

 

我們從索引的建立入手:

我們建立一個(gè) lucene 的索引時(shí)必須先建立該索引文件存放的位置,看一下代碼:

IndexWriter writer = null;

writer = new IndexWriter("c:\\index", new CJKAnalyzer(), true);

這段代碼就時(shí)建立一個(gè)索引前所必須的操作,先聲明這個(gè) IndexWriter ,實(shí)例化它你必須傳入三個(gè)參數。他們分別代表:你要建立索引文件的存放位置、你要使用索引建立的分詞方法、是否重新建立索引。這樣你就告訴 lucene 我要在 c 盤(pán)的 index 目錄下建立索引文件,我要使用車(chē)東老師的二分詞算法做分析器、我要在這個(gè)目錄下刪除以前的索引或任何文件創(chuàng )立我的索引文件。

索引的建立有三種方式,讓我一一道來(lái):

1 、 new IndexWriter(new RAMDirectory(), new StandardAnalyzer(), true);

在內存中建立索引,速度最快但是耗資源,而且重啟就沒(méi)了。

2 、 new IndexWriter(FSDirectory.getDirectory(path, true), new StandardAnalyzer(), true);

在文件系統中建立索引,這里有兩個(gè)參數,分別是:建立索引的路徑、是否要刪除當前目錄下的文件重新建立索引。

3 、 new IndexWriter("c:\\index", new CJKAnalyzer(), true);

最常見(jiàn)的一種,在制定目錄下建立索引,看了源碼你就知道這種方法也是用的第二種方式。 Lucene 的源碼:

public IndexWriter(String path, Analyzer a, boolean create)

       throws IOException {

 this(FSDirectory.getDirectory(path, create), a, create, true);

  }

我想的沒(méi)錯。

Indexwriter 性能調整參數:

第一個(gè)優(yōu)化的參數: mergeFactor 這個(gè)參數用于控制 lucene 在把索引從內存寫(xiě)入到磁盤(pán)上的文件系統時(shí)內存最大的 Document 對象的數量。這個(gè)數要根據你的計算機設置,默認情況下是 10 。

    第二個(gè)優(yōu)化的參數 maxMergeFactor 這個(gè)參數用來(lái)設置當有多少個(gè) Segment 時(shí)進(jìn)行合并操作。當然我們知道當索引文件太多的話(huà)其檢索的速度就會(huì )很慢,所以我們要當文件數量一定時(shí)讓它進(jìn)行索引的合并。這樣就可以加快索引速度,但是這個(gè)值要根據你的情況而定。當文檔數量較多時(shí)我們將值設大些,當文檔數量較少時(shí)我們將值設小些。

第三個(gè)優(yōu)化的參數: minMergeDocs 這個(gè)參數用于控制內存中文檔的數量。

 

這樣我們建立索引已經(jīng)完成,接下來(lái)我們要建立 Document 對象,因為你必須告訴我要搜索什么吧!好了,看看源碼:

File file = new File("1.txt");

Document doc = new Document();

doc.add(Field.UnIndexed("filename", file.getName()));

FileInputStream fis = new FileInputStream(file);

byte[] b = new byte[fis.available()];

fis.read(b);

String content = new String(b);

doc.add(Field.Text("content", content));

fis.close();

以上我們就完成了將 1.txt 文件放到我們的 Document 對象了。這里我們用了 Field.Text(); 這樣的操作和 doc.add(); 這樣的方法建立的。這也是建立索引的必須。

稍微介紹一下 Field ,它就是你要建立索引的字段。它分別有

類(lèi)型/方法

是否分詞

是否索引

是否存儲

常用實(shí)例

Keyword(String,String)

Keyword(String,Date)

電話(huà)號碼,身份證,人名,地名,日期

Unindexed(String,String)

文檔類(lèi)型,文檔名稱(chēng)

UnStored(String,String)

文檔的標題和內容

Text(String,String)

文檔的標題和內容

Text(String,Reader)

文檔的標題和內容

    這樣我們要建什么樣的索引就對號入座吧,只要最后我們使用 doc.add(Field.Text("content", content)); 把它添加到 Document 中就可以了。

    這時(shí)我們的文檔已經(jīng)建立好了,現在就開(kāi)始向索引中添加文檔吧!這里我們使用

writer.addDocument(doc); 來(lái)向 Indexwriter 索引中添加構造好的文檔。

這樣我們是不是就可以說(shuō)我們已經(jīng)建立完了索引呢,其實(shí)不然,我們還要優(yōu)化優(yōu)化,這樣才快嘛!對不對?

    writer.optimize(); 這樣一句話(huà)就可以實(shí)現索引優(yōu)化了,具體的優(yōu)化過(guò)程我就不說(shuō)了,是不是很簡(jiǎn)單。但是一定不要忘了哦。調用這個(gè)方法時(shí)最好建立一個(gè)合適的周期。定期進(jìn)行優(yōu)化。

    好了,這樣我們就完成了索引的建立了。

    下面我們看看縮影的合并吧!

當我們在很多地方建立了很多的索引后,想要合并這些索引我們怎么辦呢?

    使用 IndexWriter.assIndexs(New Directory[]{path});

就可以對 path 路徑下的索引合并到當前的索引中了。

    下面再看看索引的刪除吧!

    有一些過(guò)時(shí)的索引我們需要刪除,怎么辦呢?

IndexReader reader = IndexReader.open("c:\\index");

    reader.delete(0);

這樣我們就可以按照文檔的順序刪除對應的文檔了,但是這樣不太現實(shí),不對嗎?我們怎么會(huì )知道文檔的順序呢?

下面我們看看第二中方法:

IndexReader reader = IndexReader.open("c:\\index");

reader.delete(new Term("name","word1"));

reader.close();

按照字段來(lái)刪除對應的文檔,這樣合理多了。以后要刪除時(shí)就按照詞條的方式去刪除吧 !

索引鎖: write.lock , commit.lock.

write.lock 是為了避免幾個(gè)線(xiàn)程同時(shí)修改一個(gè)索引文檔而設置。當實(shí)例一個(gè) indexwrite 時(shí)建立和使用 indexReader 刪除文檔時(shí)建立。

Commit.lock 該鎖主要在 segment 在建立,合并或讀取時(shí)生成。

4          Lucene 的搜索

 

以上完成了索引的建立和一些關(guān)于索引的知識,但是光有索引是不行的,我們真正要做的檢索,這才是我們的關(guān)鍵?,F在我們看看 lucene 的檢索吧。

認識檢索從檢索的工具開(kāi)始吧! IndexSearcher 類(lèi)是 lucene 用于檢索的工具類(lèi),我們在檢索之前要得到這個(gè)類(lèi)的實(shí)例。

第一步我們看以下代碼:

IndexSearcher searcher = new IndexSearcher("c:\\index");

創(chuàng )建 IndexSearcher 實(shí)例需要告訴 lucene 索引的位置,就是你 IndexWrite 的文件路徑。

Query query = null;

Hits hits = null;

query = QueryParser.parse(key1, "name", new StandardAnalyzer());

hits = searcher.search(query);

if (hits != null) {

           if (hits.length() == 0) {

              System.out.println(" 沒(méi)有找到任何結果 ");

           } else {

              System.out.print(" 找到 ");

              for (int i = 0; i < hits.length(); i++) {

                  Document d = hits.doc(i);

                  String dname = d.get("title");

                  System.out.print(dname + "   " );

              }

           }

       }

}

以上就是一個(gè)完整的檢索過(guò)程,這里我們看見(jiàn)了個(gè) Query Hits ,這兩個(gè)類(lèi)就是比較關(guān)鍵的了,我們先從檢索結果的 Hits 類(lèi)說(shuō)起。

我們使用 Hits 經(jīng)常使用的幾個(gè)方法有:

length() :  返回搜索結果的總數量。

Doc(int n) : 放回第 n 個(gè)文檔。

Id(int n) : 返回第 n 個(gè)文檔的內部編號。

Sorce(int n) : 返回第 n 個(gè)文檔的得分。

看見(jiàn)這個(gè) Sorce(int n) 這個(gè)方法,是不是就可以聯(lián)想到搜索引擎的排序問(wèn)題呢,像百度的推廣是怎么做出來(lái)的呢 , 可想而知吧,那就說(shuō)明必定存在一中方法可以動(dòng)態(tài)的改變某片文檔的得分。對了, lucene 中可以使用 Document setBoost 方法可以改變當前文檔的 boost 因子。

下面我們看看:

Document doc1 = new Document();

doc1.add(Field.Text("contents", "word1 word"));

doc1.add(Field.Keyword("path", "path\\document1.txt"));

 doc1.setBoost(1.0f);

 

  這樣我們就在改變了篇文檔的評分了,當 boost 的值越大它的分值就越高,其出現的位置就越靠前。

讓我們再來(lái)看看 lucene 為我們提供的各種 Query 吧。

第一、    按詞條搜索 - TermQuery
query = new TermQuery(new Term("name","word1"));

hits = searcher.search(query);

這樣就可以把 field name 的所有包含 word1 的文檔檢索出來(lái)了。

第二、   “與或”搜索 - BooleanQuery

它實(shí)際是一個(gè)組合 query 看看下面的代碼:

query1 = new TermQuery(new Term("name","word1"));

query2 = new TermQuery(new Term("name","word2"));

query = new BooleanQuery();

query.add(query1, false, false);

query.add(query2, false, false);

hits = searcher.search(query);

看看 booleanQuery 的用法吧:

true & true : 表明當前加入的字句是必須要滿(mǎn)足的。相當于邏輯與。

false & true : 表明當前加入的字句是不可一被滿(mǎn)足的, 相當于邏輯非。

false & false : 表明當前加入的字句是可選的,相當于邏輯或。

true & true : 錯誤的情況。

Lucene 可以最多支持連續 1024 query 的組合。

第三、   在某一范圍內搜索 - RangeQuery

IndexSearcher searcher = new IndexSearcher("c:\\index");

     Term beginTime = new Term("time","200001");

     Term endTime = new Term("time","200005");

     Hits hits = null;

     RangeQuery query = null;

     query = new RangeQuery(beginTime, endTime, false);

     hits = searcher.search(query);

RangeQuery 的構造函數的參數分別代表起始、結束、是否包括邊界。這樣我們就可以按照要求檢索了。

第四、   使用前綴檢索 - PrefixQuery

這個(gè)檢索的機制有點(diǎn)類(lèi)似于 indexOf() 從前綴查找。這個(gè)常在英文中使用,中文中就很少使用了。代碼如下:

IndexSearcher searcher = new IndexSearcher("c:\\index");

       Term pre1 = new Term("name", "Da");

       query = new PrefixQuery(pre1);

       hits = searcher.search(query);

第五、   多關(guān)鍵字的搜索 - PhraseQuery

可以多個(gè)關(guān)鍵字同時(shí)查詢(xún)。使用如下:

query = new PhraseQuery();

       query.add(word1);

       query.add(word2);

       query.setSlop(0);

       hits = searcher.search(query);

       printResult(hits, "‘david‘ ‘mary‘ 緊緊相隔的 Document");

       query.setSlop(2);

       hits = searcher.search(query);

       printResult(hits, "‘david‘ ‘mary‘ 中相隔兩個(gè)詞的短語(yǔ) ");

    這里我們要注意 query.setSlop(); 這個(gè)方法的含義。

query.setSlop(0);  緊緊相連 (這個(gè)的條件比較苛刻)

query.setSlop(2);  相隔

第六、   使用短語(yǔ)綴搜索 - PharsePrefixQuery

使用 PharsePrefixQuery 可以很容易的實(shí)現相關(guān)短語(yǔ)的檢索功能。

實(shí)例:

query = new PhrasePrefixQuery();

       // 加入可能的所有不確定的詞

Term word1 = new Term("content", "david");

       Term word2 = new Term("content", "mary");

       Term word3 = new Term("content", "smith");

       Term word4 = new Term("content", "robert");

       query.add(new Term[]{word1, word2});

       // 加入確定的詞

       query.add(word4);

       query.setSlop(2);

       hits = searcher.search(query);

       printResult(hits, " 存在短語(yǔ) ‘david robert‘ ‘mary robert‘ 的文檔 ");

第七、   相近詞語(yǔ)的搜索 - fuzzyQuery

可以通俗的說(shuō)它是一種模糊查詢(xún)。

 

 

實(shí)例:

Term word1 = new Term("content", "david");

       Hits hits = null;

       FuzzyQuery query = null;

       query = new FuzzyQuery(word1);

       hits = searcher.search(query);

       printResult(hits," ‘david‘ 相似的詞 ");

第八、   使用通配符搜索 - WildcardQuery

實(shí)例:

IndexSearcher searcher = new IndexSearcher("c:\\index");

       Term word1 = new Term("content", "*ever");

       Term word2 = new Term("content", "wh?ever");

       Term word3 = new Term("content", "h??ever");

       Term word4 = new Term("content", "ever*");

       WildcardQuery query = null;

       Hits hits = null;

       query = new WildcardQuery(word1);

       hits = searcher.search(query);

       printResult(hits, "*ever");

       query = new WildcardQuery(word2);

       hits = searcher.search(query);

       printResult(hits, "wh?ever");     

       query = new WildcardQuery(word3);

       hits = searcher.search(query);

       printResult(hits, "h??ever");     

       query = new WildcardQuery(word4);

       hits = searcher.search(query);

       printResult(hits, "ever*");

    由上可以看出通配符?代便 1 個(gè)字符, * 代表 0 到多個(gè)字符。

Lucene 現在支持以上八中的搜索方式,我們可以根據需要選擇適合自己的搜索方式。當然上面提供的一些可能對英文還是比較有效,中文就不可取了,所以我們開(kāi)始想想百度,我們只在一個(gè)輸入框中搜索結果。有了這個(gè)疑問(wèn)我們揭開(kāi)下一章的討論吧!

查詢(xún)字符串的解析:這個(gè)就是我們經(jīng)常在一個(gè)輸入框中輸入我們要檢索的文字,交給搜索引擎去幫我們分詞。

QueryParser 類(lèi)就是對查詢(xún)字符串的解析類(lèi)。

看看它的用法:

 

query = QueryParser.parse(key1, "name", new StandardAnalyzer());

hits = searcher.search(query);

它直接返回一個(gè) Query 對象。需要傳入的參數分別是:

用戶(hù)需要查詢(xún)的字符串、需要檢索的對應字段名稱(chēng)、采用的分詞類(lèi)。

Analyzer analyzer = new CJKAnalyzer();

String[] fields = {"filename", "content"};

Query query = MultiFieldQueryParser.parse(searchword, fields, analyzer);

Hits hits = searcher.search(query);

QueryParser 的“與” “或”:

QueryParser 之間默認是或,我們想改變?yōu)榕c的話(huà)加入以下代碼:

QueryParser.setOperator(QueryParser.DEFAULT_OPERATOR_AND);

就可以了。

5          高級搜索技巧

前面我們已經(jīng)介紹了一般情況下 lucene 的使用技巧,現在我們探討一下高級搜索的技巧吧!

1、 對搜索結果進(jìn)行排序:

1) 使用 sort 類(lèi)排序:

    Sort sort = new Sort();

        hits = searcher.search(query,sort);

這種方式是使用默認的 sort 排序方式進(jìn)行排序。默認的 sort 排序是按照相關(guān)度進(jìn)行排序。即通過(guò) luence 的評分機制進(jìn)行排序。

2) 對某一字段進(jìn)行排序

       Sort sort = new Sort( content );

      hits = searcher.search(query,sort);

3) 對多個(gè)字段進(jìn)行排序

Sort sort = new Sort(new SortField[]{new SortField("title"),new SortField("contents")});

hits = searcher.search(query,sort);

2、 多域搜索和多索引搜索:

在使用 luecene 時(shí),如果查詢(xún)的只是某些 terms ,而不關(guān)心這些詞條到時(shí)來(lái)自那個(gè)字段中時(shí)。這時(shí)可以使用 MultiFieldQueryParser 類(lèi)。這個(gè)用于用戶(hù)搜索含有某個(gè)關(guān)鍵字是否存在在字段中,他們之間的關(guān)系使用 OR 連接。即不管存在在哪一個(gè)字段都會(huì )顯示顯示出來(lái)。

使用 MultiSearcher 可以滿(mǎn)足同時(shí)多索引的搜索需求。

Searcher[] searchers = new Searcher[2];

searchers[0] = new IndexSearcher(indexStoreB);

searchers[1] = new IndexSearcher(indexStoreA);

        // 創(chuàng )建一個(gè)多索引檢索器

Searcher mSearcher = new MultiSearcher(searchers);

3、     對搜索結果進(jìn)行過(guò)濾:

1)     對時(shí)間進(jìn)行過(guò)濾

         通常情況下我們對搜索結果要進(jìn)行過(guò)濾顯示,即只顯示過(guò)濾后的結果。

doc.add(Field.Keyword("datefield", DateField.timeToString(now - 1000)));

DateFilter df1 = DateFilter.Before("datefield", now);

2)         查詢(xún)過(guò)濾器

通過(guò)查詢(xún)過(guò)濾器可以過(guò)濾一部分的信息。

Filter filter = new Filter()

        {

       public BitSet bits (IndexReader reader) throws IOException

          {

            BitSet bitset = new BitSet(5);

            bitset.set (1);

            bitset.set (3);

            return bitset;

          }

        };

        // 生成帶有過(guò)濾器的查詢(xún)對象

        Query filteredquery = new FilteredQuery (query, filter);

       // 返回檢索結果

        Hits hits = searcher.search (filteredquery);

 

這樣我們就可以使用自己定義的過(guò)濾方式去過(guò)濾信息了。

3)     帶緩存的過(guò)濾器:

使用待緩存的過(guò)濾器我們可以重用過(guò)濾功能,如下:

MockFilter filter = new MockFilter();

 CachingWrapperFilter cacher = new CachingWrapperFilter(filter);

        cacher.bits(reader);

以上介紹完了現在學(xué)習 luence ,沒(méi)有太詳細的介紹它的實(shí)現,因為它對于我們來(lái)說(shuō)是一個(gè)工具,既然是工具我們就要會(huì )用就可以了。

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
[Lucene.Net] 基本用法
Lucene基本適用介紹
Lucene搜索方法總結 - Java綜合 - Java - ITeye論壇
Apache Lucene與Lucene.Net——全文檢索服務(wù)器
lucene搜索引擎技術(shù)的分析與整理
有關(guān)Lucene的問(wèn)題(4):影響Lucene對文檔打分的四種方式
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久