12银锻、tika的使用(lucene筆記)

一永品、概述

主要用于打開各種不同的文檔。也就是我們需要處理不同格式的文檔击纬,比如word鼎姐、pdf等,這個軟件就是用來處理不同格式的文檔更振。也是需要使用命令
java -jar tika-app-1.13.jar運(yùn)行炕桨。直接file->open打開相關(guān)的文檔,這樣它就會解析此文檔肯腕。

二献宫、入門(工程lucene-tika

先編寫創(chuàng)建索引的工具類:
IndexUtil.java

public void index(){
    try {
        File f = new File("E:/myeclipse/Lucene/complexFile/相關(guān)問題.docx");
        Directory dir = FSDirectory.open(new File("E:/myeclipse/Lucene/index1"));
    
        IndexWriter writer = new IndexWriter(dir, new IndexWriterConfig(Version.LUCENE_35, new MMSegAnalyzer()));
        Document doc = new Document();
        //doc.add(new Field("content", new Tika().parse(f)));
        doc.add(new Field("content", new FileReader(f)));
        writer.addDocument(doc);
        writer.close();
    } catch (CorruptIndexException e) {
        e.printStackTrace();
    } catch (LockObtainFailedException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

這里我們先不使用它tika,看看索引的情況实撒,
TestIndex.java

@Test
public void testIndex(){
    IndexUtil util = new IndexUtil();
    util.index();
}

這里我們試驗(yàn)一下對一篇word文檔進(jìn)行分詞姊途。然后我們使用luke進(jìn)行查看,發(fā)現(xiàn)里面的信息都看不懂知态,完全不能滿足我們的要求吭净。在來看使用tika的情況。注意:這里我們在添加文檔的時候也可以使用tika的方式肴甸,不需要傳遞FileReader寂殉。

  • 第一種方式
    IndexUtil.java
public String fileToTxt(File f){
    //使用AutoDetectParser可以使Tika根據(jù)實(shí)際情況自動轉(zhuǎn)換需要使用的parser,不需要再手工指定
    Parser parser = new AutoDetectParser();
    InputStream is = null;//文件輸入流
    try {
        Metadata metadata = new Metadata();
        //改變相關(guān)的內(nèi)容,Tika解析文檔時會生成的一組說明數(shù)據(jù)
        metadata.set(Metadata.AUTHOR, "yj");
        
        is = new FileInputStream(f);
        //所有解析出來的內(nèi)容會放到它的子類BodyContentHandler中
        ContentHandler handler = new BodyContentHandler();
        //用來存儲需要填入的參數(shù),最少需要設(shè)置tikaParser本身
        ParseContext context = new ParseContext();
        context.set(Parser.class, parser);//為parser指定對象
        
        parser.parse(is, handler, metadata, context);
        //獲取metadata的信息
        for(String name : metadata.names()){
            System.out.println(name + ":" + metadata.get(name));
        }
        
        return handler.toString();//解析完之后會將結(jié)果存在handler中
        
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (SAXException e) {
        e.printStackTrace();
    } catch (TikaException e) {
        e.printStackTrace();
    }finally{
        if(is != null){
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    return null;
}

說明:在試驗(yàn)之前需要導(dǎo)入相關(guān)的依賴包。其中我們實(shí)例化AutoDetectParser類來實(shí)例化一個Parser對象原在,可以讓tika根據(jù)不同的文檔類型自動轉(zhuǎn)換需要使用的Parser友扰,不需要手動指定;而Metadata表示解析文檔后生成的一些說明信息庶柿,如作者村怪、日期等內(nèi)容;ContentHandler就是用來存放解析文檔后的內(nèi)容的浮庐;ParseContext對象用來將之前的Parser設(shè)置進(jìn)來甚负。
測試:

@Test
public void testTika01(){
    IndexUtil util = new IndexUtil();
    System.out.println(util.fileToTxt(new File("E:/myeclipse/Lucene/complexFile/相關(guān)問題.docx")));
}

說明:測試之后我們可以使用luke或者tika查看相關(guān)的內(nèi)容柬焕。

  • 第二種方式
    IndexUtil.java
public String tikaTool(File f) throws IOException, TikaException{
    
    Tika tika = new Tika();
    Metadata metadata = new Metadata();
    metadata.set(Metadata.REALIZATION, "相關(guān)問題.docx");
    //獲取metadata的信息
    /*for(String name : metadata.names()){
        System.out.println(name + ":" + metadata.get(name));
    }*/
    //當(dāng)然也是可以將信息存入到metadata中的
    String str = tika.parseToString(new FileInputStream(f), metadata);
    for(String name : metadata.names()){
        System.out.println(name + ":" + metadata.get(name));
    }
    return tika.parseToString(f);
}

說明:可以看到這種方式相比第一種方式要簡單的多,但是注意梭域,默認(rèn)情況下Metadata對象中是不會有數(shù)據(jù)的斑举,這和上面那種方式不一樣,當(dāng)然我們也可以使用parseToString方法將相關(guān)信息設(shè)置到Metadata中病涨。

三富玷、對多個文件進(jìn)行索引(工程lucene-tika1

首先我們建立索引FileIndexUtil.java

package cn.itcast.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.Random;
import org.apache.commons.io.FilenameUtils;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.NumericField;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.util.Version;
import org.apache.tika.Tika;
import org.apache.tika.metadata.Metadata;
import com.chenlb.mmseg4j.analysis.MMSegAnalyzer;

public class FileIndexUtil {

    private static Directory directory = null;
    static {
        try {
            directory = FSDirectory.open(new File("E:/myeclipse/Lucene/index1"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static Directory getDirectory() {
        return directory;
    }
    
    private static Document generatorDoc(File f) throws IOException{
        Document doc = new Document();
        Metadata metadata = new Metadata();
        //通過tika進(jìn)行存儲
        doc.add(new Field("content", new Tika().parse(new FileInputStream(f), metadata)));
        //存儲頁數(shù),而像html這類文檔是沒有頁數(shù)的既穆,需要判斷
        int pages = 0;
        try{
            pages = Integer.parseInt(metadata.get("xmpTPg:NPages"));
        }catch(Exception e){
            e.printStackTrace();
        }
        doc.add(new NumericField("page",Field.Store.YES, true).setIntValue(pages));
        
        //存儲標(biāo)題
        doc.add(new Field("title", FilenameUtils.getBaseName(f.getName()), Field.Store.YES, Field.Index.ANALYZED));
        //存儲文件類型
        doc.add(new Field("type", FilenameUtils.getExtension(f.getName()), Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS));
        doc.add(new Field("filename", f.getName(),Field.Store.YES, Field.Index.NOT_ANALYZED));
        doc.add(new Field("path", f.getAbsolutePath(),Field.Store.YES, Field.Index.NOT_ANALYZED));
        doc.add(new NumericField("date", Field.Store.YES, true).setLongValue(f.lastModified()));
        doc.add(new NumericField("size", Field.Store.YES, true).setIntValue((int) (f.length())));
        return doc;
    }

    // 創(chuàng)建索引
    public static void index(boolean hasNew) {
        IndexWriter writer = null;
        try {
            writer = new IndexWriter(directory, new IndexWriterConfig(
                    Version.LUCENE_35, new MMSegAnalyzer()));
            if (hasNew) {
                writer.deleteAll();//如果我們要新建索引赎懦,那么將之前創(chuàng)建的刪除
            }
            File file = new File("E:/myeclipse/Lucene/complexFile");

            Document doc = null;
            for (File f : file.listFiles()) {
                doc = generatorDoc(f);
                writer.addDocument(doc);
            }
        } catch (CorruptIndexException e) {
            e.printStackTrace();
        } catch (LockObtainFailedException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (CorruptIndexException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

說明:這里在創(chuàng)建索引時就不使用FileReader了,而是使用Tika對象幻工,我們將輸入流傳遞進(jìn)去励两。其他內(nèi)容和之前一樣,只是這里如果我們對一個html文檔進(jìn)行索引時囊颅,這個索引是沒有頁數(shù)的当悔,所以我們需要判斷,不然會報(bào)異常迁酸。使用Tika對文檔進(jìn)行解析之后我們再使用IndexWriter進(jìn)行寫入。

測試:

@Test
public void testTika03(){
    FileIndexUtil.index(true);
}

說明:在測試的時候俭正,雖然通過了測試奸鬓,但是卻報(bào)下面這個異常:

com.drew.lang.BufferBoundsException: Attempt to read from beyond end of underlying data source (requested index: 6, requested count: 2, max index: 5)

不知道是不是這個原因,導(dǎo)致我的索引感覺有問題掸读,最明顯的就是沒有進(jìn)行中文分詞串远,雖然我給出的分詞器是MMSEG。最后我將tika換成1.0版本就好了儿惫。而這里之所以沒有進(jìn)行中文分詞澡罚,是因?yàn)?code>MMSEG的包用的不對,應(yīng)該使用mmseg4j-all-1.8.5-with-dic.jar肾请。這樣就正確了留搔。我們可以使用luke進(jìn)行查看。

我們在編寫一個搜索方法:
SearchUtill.java

package cn.itcast.util;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;

public class SearchUtill {
    
    public void search01() throws Exception{
        IndexSearcher searcher = new IndexSearcher(IndexReader.open(FileIndexUtil.getDirectory()));
        TermQuery query = new TermQuery(new Term("content", "網(wǎng)絡(luò)"));
        TopDocs tds = searcher.search(query, 20);
        for(ScoreDoc sd : tds.scoreDocs){
            Document doc = searcher.doc(sd.doc);
            System.out.println(doc.get("title"));
        }
        searcher.close();
    }
}

測試:

@Test
public void testTika04() throws Exception{
    SearchUtill util = new SearchUtill();
    util.search01();
}

說明:我們可以對相關(guān)關(guān)鍵詞進(jìn)行搜索铛铁,效率挺高的隔显。

四、高亮顯示

未完待續(xù)饵逐。括眠。。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末倍权,一起剝皮案震驚了整個濱河市掷豺,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖当船,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件题画,死亡現(xiàn)場離奇詭異,居然都是意外死亡生年,警方通過查閱死者的電腦和手機(jī)婴程,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來抱婉,“玉大人档叔,你說我怎么就攤上這事≌艏ǎ” “怎么了衙四?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長患亿。 經(jīng)常有香客問我传蹈,道長,這世上最難降的妖魔是什么步藕? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任惦界,我火速辦了婚禮,結(jié)果婚禮上咙冗,老公的妹妹穿的比我還像新娘沾歪。我一直安慰自己,他們只是感情好雾消,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布灾搏。 她就那樣靜靜地躺著,像睡著了一般立润。 火紅的嫁衣襯著肌膚如雪狂窑。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天桑腮,我揣著相機(jī)與錄音泉哈,去河邊找鬼。 笑死破讨,一個胖子當(dāng)著我的面吹牛旨巷,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播添忘,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼采呐,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了搁骑?” 一聲冷哼從身側(cè)響起斧吐,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤又固,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后煤率,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體仰冠,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年蝶糯,在試婚紗的時候發(fā)現(xiàn)自己被綠了洋只。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡昼捍,死狀恐怖识虚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情妒茬,我是刑警寧澤担锤,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站乍钻,受9級特大地震影響肛循,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜银择,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一多糠、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧浩考,春花似錦夹孔、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽害捕。三九已至绿淋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間尝盼,已是汗流浹背吞滞。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留盾沫,地道東北人裁赠。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像赴精,于是被迫代替她去往敵國和親佩捞。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理蕾哟,服務(wù)發(fā)現(xiàn)一忱,斷路器莲蜘,智...
    卡卡羅2017閱讀 134,707評論 18 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法帘营,內(nèi)部類的語法票渠,繼承相關(guān)的語法,異常的語法芬迄,線程的語...
    子非魚_t_閱讀 31,664評論 18 399
  • 1 XML解析No29 【 XML:可拓展標(biāo)記語言问顷,語言和HTML類似,也是一種標(biāo)記語言禀梳。 特點(diǎn):標(biāo)記是自定義...
    征程_Journey閱讀 1,656評論 0 9
  • 一. Java基礎(chǔ)部分.................................................
    wy_sure閱讀 3,814評論 0 11
  • 清晨的許昌市被白霧籠罩杜窄,增添一股朦朧的凄美,似乎訴說那三國英雄豪杰出皇,也如霧般地消逝在歲月洪流里羞芍。 “聞聽三國事,每...
    輕醒閱讀 240評論 0 4