1.1. 數(shù)據(jù)分類
結(jié)構(gòu)化數(shù)據(jù):指具有固定格式或有限長(zhǎng)度的數(shù)據(jù),如數(shù)據(jù)庫(kù)嚼黔,元數(shù)據(jù)等细层。
非結(jié)構(gòu)化數(shù)據(jù):指不定長(zhǎng)或無(wú)固定格式的數(shù)據(jù),如郵件唬涧,word文檔等磁盤上的文件
1.2. 非結(jié)構(gòu)化數(shù)據(jù)查詢方法
將非結(jié)構(gòu)化數(shù)據(jù)中的一部分信息提取出來(lái)疫赎,重新組織,使其變得有一定結(jié)構(gòu)碎节,然后對(duì)此有一定結(jié)構(gòu)的數(shù)據(jù)進(jìn)行搜索捧搞,從而達(dá)到搜索相對(duì)較快的目的。這部分從非結(jié)構(gòu)化數(shù)據(jù)中提取出的然后重新組織的信息,我們稱之索引胎撇。
例如:字典介粘。字典的拼音表和部首檢字表就相當(dāng)于字典的索引,對(duì)每一個(gè)字的解釋是非結(jié)構(gòu)化的晚树,如果字典沒(méi)有音節(jié)表和部首檢字表姻采,在茫茫辭海中找一個(gè)字只能順序掃描。然而字的某些信息可以提取出來(lái)進(jìn)行結(jié)構(gòu)化處理爵憎,比如讀音慨亲,就比較結(jié)構(gòu)化,分聲母和韻母宝鼓,分別只有幾種可以一一列舉刑棵,于是將讀音拿出來(lái)按一定的順序排列,每一項(xiàng)讀音都指向此字的詳細(xì)解釋的頁(yè)數(shù)愚铡。我們搜索時(shí)按結(jié)構(gòu)化的拼音搜到讀音蛉签,然后按其指向的頁(yè)數(shù),便可找到我們的非結(jié)構(gòu)化數(shù)據(jù)——也即對(duì)字的解釋茂附。
這種先建立索引正蛙,再對(duì)索引進(jìn)行搜索的過(guò)程就叫全文檢索(Full-text Search)督弓。
雖然創(chuàng)建索引的過(guò)程也是非常耗時(shí)的营曼,但是索引一旦創(chuàng)建就可以多次使用,全文檢索主要處理的是查詢愚隧,所以耗時(shí)間創(chuàng)建索引是值得的蒂阱。
2.1. 可以使用Lucene實(shí)現(xiàn)全文檢索
2.2.1. 獲取原始文檔
Lucene不提供信息采集的類庫(kù),需要自己編寫一個(gè)爬蟲(chóng)程序?qū)崿F(xiàn)信息采集狂塘,也可以通過(guò)一些開(kāi)源軟件實(shí)現(xiàn)信息采集录煤,如下:
Nutch(http://lucene.apache.org/nutch), Nutch是apache的一個(gè)子項(xiàng)目,包括大規(guī)模爬蟲(chóng)工具荞胡,能夠抓取和分辨web網(wǎng)站數(shù)據(jù)妈踊。
jsoup(http://jsoup.org/ ),jsoup 是一款Java 的HTML解析器泪漂,可直接解析某個(gè)URL地址廊营、HTML文本內(nèi)容。它提供了一套非常省力的API萝勤,可通過(guò)DOM露筒,CSS以及類似于jQuery的操作方法來(lái)取出和操作數(shù)據(jù)。
heritrix(http://sourceforge.net/projects/archive-crawler/files/)敌卓,Heritrix 是一個(gè)由 java 開(kāi)發(fā)的慎式、開(kāi)源的網(wǎng)絡(luò)爬蟲(chóng),用戶可以使用它來(lái)從網(wǎng)上抓取想要的資源。其最出色之處在于它良好的可擴(kuò)展性瘪吏,方便用戶實(shí)現(xiàn)自己的抓取邏輯癣防。
本案例我們要獲取磁盤上文件的內(nèi)容,可以通過(guò)文件流來(lái)讀取文本文件的內(nèi)容肪虎,對(duì)于pdf劣砍、doc、xls等文件可通過(guò)第三方提供的解析工具讀取文件內(nèi)容扇救,比如Apache POI讀取doc和xls的文件內(nèi)容刑枝。
2.2.2. 創(chuàng)建文檔對(duì)象
在索引前需要將原始內(nèi)容創(chuàng)建成文檔(Document),文檔中包括一個(gè)一個(gè)的域(Field)迅腔,域中存儲(chǔ)內(nèi)容装畅。
注意:每個(gè)Document可以有多個(gè)Field,不同的Document可以有不同的Field沧烈,同一個(gè)Document可以有相同的Field(域名和域值都相同)
每個(gè)文檔都有一個(gè)唯一的編號(hào)掠兄,就是文檔id。
此例子中
2.2.3. 分析文檔
需要再對(duì)域中的內(nèi)容進(jìn)行分析锌雀,分析的過(guò)程是經(jīng)過(guò)對(duì)原始文檔提取單詞蚂夕、將字母轉(zhuǎn)為小寫、去除標(biāo)點(diǎn)符號(hào)腋逆、去除停用詞等過(guò)程生成最終的語(yǔ)匯單元婿牍,可以將語(yǔ)匯單元理解為一個(gè)一個(gè)的單詞。
比如下邊的文檔經(jīng)過(guò)分析如下:
原文檔內(nèi)容:
Lucene is a Java full-text search engine. Lucene is not a complete
application, but rather a code library and API that can easily be used
to add search capabilities to applications.
分析后得到的語(yǔ)匯單元:
lucene惩歉、java等脂、full、search撑蚌、engine上遥。。争涌。粉楚。
每個(gè)單詞叫做一個(gè)Term,不同的域中拆分出來(lái)的相同的單詞是不同的term亮垫。term中包含兩部分一部分是文檔的域名模软,另一部分是單詞的內(nèi)容。
例如:文件名中包含apache和文件內(nèi)容中包含的apache是不同的term包警。
2.2.4. 創(chuàng)建索引
對(duì)所有文檔分析得出的語(yǔ)匯單元進(jìn)行索引撵摆,索引的目的是為了搜索
注意:創(chuàng)建索引是對(duì)語(yǔ)匯單元索引,通過(guò)詞語(yǔ)找文檔害晦,這種索引的結(jié)構(gòu)叫倒排索引結(jié)構(gòu)特铝。
傳統(tǒng)方法是根據(jù)文件找到該文件的內(nèi)容暑中,在文件內(nèi)容中匹配搜索關(guān)鍵字,這種方法是順序掃描方法鲫剿,數(shù)據(jù)量大鳄逾、搜索慢。
2.2.5. 查詢索引
用戶輸入查詢關(guān)鍵字執(zhí)行搜索之前需要先構(gòu)建一個(gè)查詢對(duì)象灵莲,查詢對(duì)象中可以指定查詢要搜索的Field文檔域雕凹、查詢關(guān)鍵字等,查詢對(duì)象會(huì)生成具體的查詢語(yǔ)法政冻,
例如:
語(yǔ)法 “fileName:lucene”表示要搜索Field域的內(nèi)容為“l(fā)ucene”的文檔
搜索過(guò)程就是在索引上查找域?yàn)閒ileName枚抵,并且關(guān)鍵字為L(zhǎng)ucene的term,并根據(jù)term找到文檔id列表明场。
3.1. Lucene應(yīng)用
3.1.1. 功能一:創(chuàng)建索引庫(kù)
3.1.2. Field域的屬性
代碼實(shí)現(xiàn)
//創(chuàng)建索引
@Test
public void createIndex() throws Exception {
//指定索引庫(kù)存放的路徑
//D:\temp\0108\index
Directory directory = FSDirectory.open(new File("D:\\temp\\0108\\index"));
//索引庫(kù)還可以存放到內(nèi)存中
//Directory directory = new RAMDirectory();
//創(chuàng)建一個(gè)標(biāo)準(zhǔn)分析器
Analyzer analyzer = new StandardAnalyzer();
//創(chuàng)建indexwriterCofig對(duì)象
//第一個(gè)參數(shù): Lucene的版本信息汽摹,可以選擇對(duì)應(yīng)的lucene版本也可以使用LATEST
//第二根參數(shù):分析器對(duì)象
IndexWriterConfig config = new IndexWriterConfig(Version.LATEST, analyzer);
//創(chuàng)建indexwriter對(duì)象
IndexWriter indexWriter = new IndexWriter(directory, config);
//原始文檔的路徑D:\傳智播客\01.課程\04.lucene\01.參考資料\searchsource
File dir = new File("D:\\傳智播客\\01.課程\\04.lucene\\01.參考資料\\searchsource");
for (File f : dir.listFiles()) {
//文件名
String fileName = f.getName();
//文件內(nèi)容
String fileContent = FileUtils.readFileToString(f);
//文件路徑
String filePath = f.getPath();
//文件的大小
long fileSize = FileUtils.sizeOf(f);
//創(chuàng)建文件名域
//第一個(gè)參數(shù):域的名稱
//第二個(gè)參數(shù):域的內(nèi)容
//第三個(gè)參數(shù):是否存儲(chǔ)
Field fileNameField = new TextField("filename", fileName, Store.YES);
//文件內(nèi)容域
Field fileContentField = new TextField("content", fileContent, Store.YES);
//文件路徑域(不分析、不索引苦锨、只存儲(chǔ))
Field filePathField = new StoredField("path", filePath);
//文件大小域
Field fileSizeField = new LongField("size", fileSize, Store.YES);
//創(chuàng)建document對(duì)象
Document document = new Document();
document.add(fileNameField);
document.add(fileContentField);
document.add(filePathField);
document.add(fileSizeField);
//創(chuàng)建索引逼泣,并寫入索引庫(kù)
indexWriter.addDocument(document);
}
//關(guān)閉indexwriter
indexWriter.close();
}
3.2.1. 功能二:查詢索引
代碼實(shí)現(xiàn)
//查詢索引庫(kù)
@Test
public void searchIndex() throws Exception {
//指定索引庫(kù)存放的路徑
//D:\temp\0108\index
Directory directory = FSDirectory.open(new File("D:\\temp\\0108\\index"));
//創(chuàng)建indexReader對(duì)象
IndexReader indexReader = DirectoryReader.open(directory);
//創(chuàng)建indexsearcher對(duì)象
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
//創(chuàng)建查詢
Query query = new TermQuery(new Term("filename", "apache"));
//執(zhí)行查詢
//第一個(gè)參數(shù)是查詢對(duì)象,第二個(gè)參數(shù)是查詢結(jié)果返回的最大值
TopDocs topDocs = indexSearcher.search(query, 10);
//查詢結(jié)果的總條數(shù)
System.out.println("查詢結(jié)果的總條數(shù):"+ topDocs.totalHits);
//遍歷查詢結(jié)果
//topDocs.scoreDocs存儲(chǔ)了document對(duì)象的id
for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
//scoreDoc.doc屬性就是document對(duì)象的id
//根據(jù)document的id找到document對(duì)象
Document document = indexSearcher.doc(scoreDoc.doc);
System.out.println(document.get("filename"));
//System.out.println(document.get("content"));
System.out.println(document.get("path"));
System.out.println(document.get("size"));
}
//關(guān)閉indexreader對(duì)象
indexReader.close();
}
3.3 功能三:分析器
3.3.1常規(guī)分析器的分詞效果
//查看標(biāo)準(zhǔn)分析器的分詞效果
public void testTokenStream() throws Exception {
//創(chuàng)建一個(gè)標(biāo)準(zhǔn)分析器對(duì)象
Analyzer analyzer = new StandardAnalyzer();
//獲得tokenStream對(duì)象
//第一個(gè)參數(shù):域名舟舒,可以隨便給一個(gè)
//第二個(gè)參數(shù):要分析的文本內(nèi)容
TokenStream tokenStream = analyzer.tokenStream("test", "The Spring Framework provides a comprehensive programming and configuration model.");
//添加一個(gè)引用拉庶,可以獲得每個(gè)關(guān)鍵詞
CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);
//添加一個(gè)偏移量的引用,記錄了關(guān)鍵詞的開(kāi)始位置以及結(jié)束位置
OffsetAttribute offsetAttribute = tokenStream.addAttribute(OffsetAttribute.class);
//將指針調(diào)整到列表的頭部
tokenStream.reset();
//遍歷關(guān)鍵詞列表秃励,通過(guò)incrementToken方法判斷列表是否結(jié)束
while(tokenStream.incrementToken()) {
//關(guān)鍵詞的起始位置
System.out.println("start->" + offsetAttribute.startOffset());
//取關(guān)鍵詞
System.out.println(charTermAttribute);
//結(jié)束位置
System.out.println("end->" + offsetAttribute.endOffset());
}
tokenStream.close();
}
3.3.2 中文分析器
Lucene自帶中文分詞器
? StandardAnalyzer:
單字分詞:就是按照中文一個(gè)字一個(gè)字地進(jìn)行分詞氏仗。如:“我愛(ài)中國(guó)”,
效果:“我”莺治、“愛(ài)”廓鞠、“中”帚稠、“國(guó)”谣旁。
? CJKAnalyzer:
二分法分詞:按兩個(gè)字進(jìn)行切分。如:“我是中國(guó)人”滋早,效果:“我是”榄审、“是中”、“中國(guó)”“國(guó)人”杆麸。
上邊兩個(gè)分詞器無(wú)法滿足需求搁进。
? SmartChineseAnalyzer:
對(duì)中文支持較好,但擴(kuò)展性差昔头,擴(kuò)展詞庫(kù)饼问,禁用詞庫(kù)和同義詞庫(kù)等不好處理
第三方中文分析器
· paoding: 庖丁解牛最新版在 https://code.google.com/p/paoding/ 中最多支持Lucene 3.0,且最新提交的代碼在 2008-06-03揭斧,在svn中最新也是2010年提交莱革,已經(jīng)過(guò)時(shí),不予考慮。
· mmseg4j:最新版已從 https://code.google.com/p/mmseg4j/ 移至 https://github.com/chenlb/mmseg4j-solr盅视,支持Lucene 4.10捐名,且在github中最新提交代碼是2014年6月,從09年~14年一共有:18個(gè)版本闹击,也就是一年幾乎有3個(gè)大小版本镶蹋,有較大的活躍度,用了mmseg算法赏半。
· IK-analyzer: 最新版在https://code.google.com/p/ik-analyzer/上贺归,支持Lucene 4.10從2006年12月推出1.0版開(kāi)始, IKAnalyzer已經(jīng)推出了4個(gè)大版本断箫。最初牧氮,它是以開(kāi)源項(xiàng)目Luence為應(yīng)用主體的,結(jié)合詞典分詞和文法分析算法的中文分詞組件瑰枫。從3.0版本開(kāi) 始踱葛,IK發(fā)展為面向Java的公用分詞組件,獨(dú)立于Lucene項(xiàng)目光坝,同時(shí)提供了對(duì)Lucene的默認(rèn)優(yōu)化實(shí)現(xiàn)尸诽。在2012版本中,IK實(shí)現(xiàn)了簡(jiǎn)單的分詞 歧義排除算法盯另,標(biāo)志著IK分詞器從單純的詞典分詞向模擬語(yǔ)義分詞衍化性含。 但是也就是2012年12月后沒(méi)有在更新。
· ansj_seg:最新版本在 https://github.com/NLPchina/ansj_seg tags僅有1.1版本鸳惯,從2012年到2014年更新了大小6次商蕴,但是作者本人在2014年10月10日說(shuō)明:“可能我以后沒(méi)有精力來(lái)維護(hù)ansj_seg了”,現(xiàn)在由”nlp_china”管理芝发。2014年11月有更新绪商。并未說(shuō)明是否支持Lucene,是一個(gè)由CRF(條件隨機(jī)場(chǎng))算法所做的分詞算法辅鲸。
· imdict-chinese-analyzer:最新版在 https://code.google.com/p/imdict-chinese-analyzer/ 格郁, 最新更新也在2009年5月,下載源碼独悴,不支持Lucene 4.10 例书。是利用HMM(隱馬爾科夫鏈)算法。
· Jcseg:最新版本在git.oschina.net/lionsoul/jcseg刻炒,支持Lucene 4.10决采,作者有較高的活躍度。利用mmseg算法坟奥。
3.3.3 Analyzer使用時(shí)機(jī)
- 索引時(shí)使用Analyzer:對(duì)文檔域內(nèi)容進(jìn)行分析树瞭,需要經(jīng)過(guò)Analyzer分析器處理生成語(yǔ)匯單元(Token)暂幼。
- 搜索時(shí)使用Analyzer:對(duì)搜索關(guān)鍵字進(jìn)行分析、分詞處理移迫,使用分析后每個(gè)詞語(yǔ)進(jìn)行搜索
注意:搜索使用的分析器要和索引使用的分析器一致旺嬉。
3.4 功能四:索引庫(kù)的維護(hù)
//添加索引
@Test
public void addDocument() throws Exception {
//索引庫(kù)存放路徑
Directory directory = FSDirectory.open(new File("D:\\temp\\0108\\index"));
IndexWriterConfig config = new IndexWriterConfig(Version.LATEST, new IKAnalyzer());
//創(chuàng)建一個(gè)indexwriter對(duì)象
IndexWriter indexWriter = new IndexWriter(directory, config);
//創(chuàng)建一個(gè)Document對(duì)象
Document document = new Document();
//向document對(duì)象中添加域。
//不同的document可以有不同的域厨埋,同一個(gè)document可以有相同的域邪媳。
document.add(new TextField("filename", "新添加的文檔", Store.YES));
document.add(new TextField("content", "新添加的文檔的內(nèi)容", Store.NO));
document.add(new TextField("content", "新添加的文檔的內(nèi)容第二個(gè)content", Store.YES));
document.add(new TextField("content1", "新添加的文檔的內(nèi)容要能看到", Store.YES));
//添加文檔到索引庫(kù)
indexWriter.addDocument(document);
//關(guān)閉indexwriter
indexWriter.close();
}
3.4.1. 索引庫(kù)的添加
//添加索引
@Test
public void addDocument() throws Exception {
//索引庫(kù)存放路徑
Directory directory = FSDirectory.open(new File("D:\\temp\\0108\\index"));
IndexWriterConfig config = new IndexWriterConfig(Version.LATEST, new IKAnalyzer());
//創(chuàng)建一個(gè)indexwriter對(duì)象
IndexWriter indexWriter = new IndexWriter(directory, config);
//創(chuàng)建一個(gè)Document對(duì)象
Document document = new Document();
//向document對(duì)象中添加域。
//不同的document可以有不同的域荡陷,同一個(gè)document可以有相同的域。
document.add(new TextField("filename", "新添加的文檔", Store.YES));
document.add(new TextField("content", "新添加的文檔的內(nèi)容", Store.NO));
document.add(new TextField("content", "新添加的文檔的內(nèi)容第二個(gè)content", Store.YES));
document.add(new TextField("content1", "新添加的文檔的內(nèi)容要能看到", Store.YES));
//添加文檔到索引庫(kù)
indexWriter.addDocument(document);
//關(guān)閉indexwriter
indexWriter.close();
}
3.4.3. 索引庫(kù)的刪除
- 刪除全部
//刪除全部索引
@Test
public void deleteAllIndex() throws Exception {
IndexWriter indexWriter = getIndexWriter();
//刪除全部索引
indexWriter.deleteAll();
//關(guān)閉indexwriter
indexWriter.close();
}
- 指定查詢條件刪除
//根據(jù)查詢條件刪除索引
@Test
public void deleteIndexByQuery() throws Exception {
IndexWriter indexWriter = getIndexWriter();
//創(chuàng)建一個(gè)查詢條件
Query query = new TermQuery(new Term("filename", "apache"));
//根據(jù)查詢條件刪除
indexWriter.deleteDocuments(query);
//關(guān)閉indexwriter
indexWriter.close();
}
- 索引庫(kù)的修改
//修改索引庫(kù)
@Test
public void updateIndex() throws Exception {
IndexWriter indexWriter = getIndexWriter();
//創(chuàng)建一個(gè)Document對(duì)象
Document document = new Document();
//向document對(duì)象中添加域极颓。
//不同的document可以有不同的域狂秘,同一個(gè)document可以有相同的域破衔。
document.add(new TextField("filename", "要更新的文檔", Store.YES));
document.add(new TextField("content", "2013年11月18日 - Lucene 簡(jiǎn)介 Lucene 是一個(gè)基于 Java 的全文信息檢索工具包,它不是一個(gè)完整的搜索應(yīng)用程序,而是為你的應(yīng)用程序提供索引和搜索功能忠售。", Store.YES));
indexWriter.updateDocument(new Term("content", "java"), document);
//關(guān)閉indexWriter
indexWriter.close();
}
3.5.1 Lucene索引庫(kù)查詢
可通過(guò)兩種方法創(chuàng)建查詢對(duì)象:
1)使用Lucene提供Query子類
Query是一個(gè)抽象類泰佳,lucene提供了很多查詢對(duì)象,比如TermQuery項(xiàng)精確查詢,NumericRangeQuery數(shù)字范圍查詢等。
如下代碼:
Query query = new TermQuery(new Term("name", "lucene"));
2)使用QueryParse解析查詢表達(dá)式
QueryParse會(huì)將用戶輸入的查詢表達(dá)式解析成Query對(duì)象實(shí)例险绘。
如下代碼:
QueryParser queryParser = new QueryParser("name", new IKAnalyzer());
Query query = queryParser.parse("name:lucene");
3.5.2. 使用query的子類查詢
①M(fèi)atchAllDocsQuery
使用MatchAllDocsQuery查詢索引目錄中的所有文檔
@Test
public void testMatchAllDocsQuery() throws Exception {
IndexSearcher indexSearcher = getIndexSearcher();
//創(chuàng)建查詢條件
Query query = new MatchAllDocsQuery();
//執(zhí)行查詢
printResult(query, indexSearcher);
}
②TermQuery
TermQuery渺氧,通過(guò)項(xiàng)查詢,TermQuery不使用分析器所以建議匹配不分詞的Field域查詢潮太,比如訂單號(hào)、分類ID號(hào)等景埃。
指定要查詢的域和要查詢的關(guān)鍵詞。
//使用Termquery查詢
@Test
public void testTermQuery() throws Exception {
IndexSearcher indexSearcher = getIndexSearcher();
//創(chuàng)建查詢對(duì)象
Query query = new TermQuery(new Term("content", "lucene"));
//執(zhí)行查詢
TopDocs topDocs = indexSearcher.search(query, 10);
//共查詢到的document個(gè)數(shù)
System.out.println("查詢結(jié)果總數(shù)量:" + topDocs.totalHits);
//遍歷查詢結(jié)果
for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
Document document = indexSearcher.doc(scoreDoc.doc);
System.out.println(document.get("filename"));
//System.out.println(document.get("content"));
System.out.println(document.get("path"));
System.out.println(document.get("size"));
}
//關(guān)閉indexreader
indexSearcher.getIndexReader().close();
}
③NumericRangeQuery
可以根據(jù)數(shù)值范圍查詢。
//數(shù)值范圍查詢
@Test
public void testNumericRangeQuery() throws Exception {
IndexSearcher indexSearcher = getIndexSearcher();
//創(chuàng)建查詢
//參數(shù):
//1.域名
//2.最小值
//3.最大值
//4.是否包含最小值
//5.是否包含最大值
Query query = NumericRangeQuery.newLongRange("size", 1l, 1000l, true, true);
//執(zhí)行查詢
printResult(query, indexSearcher);
}
④BooleanQuery
可以組合查詢條件乞巧。
//組合條件查詢
@Test
public void testBooleanQuery() throws Exception {
IndexSearcher indexSearcher = getIndexSearcher();
//創(chuàng)建一個(gè)布爾查詢對(duì)象
BooleanQuery query = new BooleanQuery();
//創(chuàng)建第一個(gè)查詢條件
Query query1 = new TermQuery(new Term("filename", "apache"));
Query query2 = new TermQuery(new Term("content", "apache"));
//組合查詢條件
query.add(query1, Occur.MUST);
query.add(query2, Occur.MUST);
//執(zhí)行查詢
printResult(query, indexSearcher);
}
//Occur.MUST:必須滿足此條件,相當(dāng)于and
//Occur.SHOULD:應(yīng)該滿足摊鸡,但是不滿足也可以绽媒,相當(dāng)于or
//Occur.MUST_NOT:必須不滿足。相當(dāng)于not
3.5.3. 使用queryparser查詢
通過(guò)QueryParser也可以創(chuàng)建Query免猾,QueryParser提供一個(gè)Parse方法是辕,此方法可以直接根據(jù)查詢語(yǔ)法來(lái)查詢。Query對(duì)象執(zhí)行的查詢語(yǔ)法可通過(guò)System.out.println(query);查詢猎提。
需要使用到分析器获三。建議創(chuàng)建索引時(shí)使用的分析器和查詢索引時(shí)使用的分析器要一致。
程序?qū)崿F(xiàn)
@Test
public void testQueryParser() throws Exception {
IndexSearcher indexSearcher = getIndexSearcher();
//創(chuàng)建queryparser對(duì)象
//第一個(gè)參數(shù)默認(rèn)搜索的域
//第二個(gè)參數(shù)就是分析器對(duì)象
QueryParser queryParser = new QueryParser("content", new IKAnalyzer());
Query query = queryParser.parse("Lucene是java開(kāi)發(fā)的");
//執(zhí)行查詢
printResult(query, indexSearcher);
}
查詢語(yǔ)法
1锨苏、基礎(chǔ)的查詢語(yǔ)法疙教,關(guān)鍵詞查詢:
域名+“:”+搜索的關(guān)鍵字
例如:content:java
2、范圍查詢
域名+“:”+[最小值 TO 最大值]
例如:size:[1 TO 1000]
范圍查詢?cè)趌ucene中支持?jǐn)?shù)值類型伞租,不支持字符串類型贞谓。在solr中支持字符串類型。
3葵诈、組合條件查詢
1)+條件1 +條件2:兩個(gè)條件之間是并且的關(guān)系and
例如:+filename:apache +content:apache
2)+條件1 條件2:必須滿足第一個(gè)條件裸弦,應(yīng)該滿足第二個(gè)條件
例如:+filename:apache content:apache
3)條件1 條件2:兩個(gè)條件滿足其一即可。
例如:filename:apache content:apache
4)-條件1 條件2:必須不滿足條件1作喘,要滿足條件2
例如:-filename:apache content:apache
Occur.MUST 查詢條件必須滿足理疙,相當(dāng)于and → +(加號(hào))
Occur.SHOULD 查詢條件可選,相當(dāng)于or → 空(不用符號(hào))
Occur.MUST_NOT 查詢條件不能滿足徊都,相當(dāng)于not非 → -(減號(hào))
第二種寫法:
條件1 AND 條件2
條件1 OR 條件2
條件1 NOT 條件2
MultiFieldQueryParser
可以指定多個(gè)默認(rèn)搜索域
@Test
public void testMultiFiledQueryParser() throws Exception {
IndexSearcher indexSearcher = getIndexSearcher();
//可以指定默認(rèn)搜索的域是多個(gè)
String[] fields = {"filename", "content"};
//創(chuàng)建一個(gè)MulitFiledQueryParser對(duì)象
MultiFieldQueryParser queryParser = new MultiFieldQueryParser(fields, new IKAnalyzer());
Query query = queryParser.parse("java AND apache");
System.out.println(query);
//執(zhí)行查詢
printResult(query, indexSearcher);
}
e.g. 本文僅供個(gè)人筆記使用沪斟,借鑒部分網(wǎng)上資料。