Lucene 全功能


package com.diyi.util;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MultiSearcher;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.RangeQuery;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.WildcardQuery;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleFragmenter;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.mira.lucene.analysis.IK_CAnalyzer;

import com.diyi.core.web.BaseAction;
public class LuceneTest extends BaseAction{

private static final long serialVersionUID = 1L;
/*
* lucene全功能,幾乎包含了大部分查詢綜合起來。,
*/
static String path="e:\\Lucene測試\\";
static String ArticleTitle="ArticleTitle";
static String ArticleText="ArticleText";
static String ArticleTime="ArticleTime";
public static void index() throws Exception {
/* 創建索引初始化,執行這些語句將創建或清空d:\\save\\目錄下所有索引 */
File file=new File(path);
if(file.isDirectory())
{
file.delete();
}
IK_CAnalyzer ikAnalyzer=new IK_CAnalyzer();
IndexWriter writer1 = new IndexWriter(path,ikAnalyzer, true);
writer1.close();
// IndexReader indexReader=IndexReader.open(path);
// indexReader.deleteDocument(1);
/*
* 往創建的初始化索引中添加索引內容,StandardAnalyzer表示用lucene自帶的標準分詞機制,
* false表示不覆蓋原來該目錄的索引,細心的讀者可能已經發現, 這句話和上面的那句就這個false不一樣
*/
IndexWriter writer2 = new IndexWriter(path,
ikAnalyzer, false);
/* 創建一份文件 */
Document doc1 = new Document();
/*
* 創建一個域ArticleTitle,並往這個域裏面添加內容 "Field.Store.YES"表示域裏面的內容將被存儲到索引
* "Field.Index.TOKENIZED"表示域裏面的內容將被索引,以便用來搜索
* Lucene給文檔的字段設定三個布爾變量: 索引(indexed), 存儲(stored), 切詞(tokenized) ,
*/
Field field1 = new Field(ArticleTitle, "上海2010年世博會,hot,GOOGLE和Yahoo 贊助,test,中華人民共和國萬歲", Field.Store.YES,
Field.Index.TOKENIZED);
/* 往文件裏添加這個域 */
doc1.add(field1);
/* 同理:創建另外一個域ArticleText,並往這個域裏面添加內容 */
Field field2 = new Field(ArticleText, "這是一屆創造綠色環境,點燃激情,影響深遠的博覽會....god..Hotmail,text,foam,OpenOffica",
Field.Store.YES, Field.Index.TOKENIZED);
doc1.add(field2);

Field field3 = new Field(ArticleTime, "2009",
Field.Store.YES, Field.Index.TOKENIZED);
doc1.add(field3);
// 在這裏還可以添加其他域
/* 添加這份文件到索引 */
writer2.addDocument(doc1);

/* 同理:創建第二份文件 */
Document doc2 = new Document();
field1 = new Field(ArticleTitle, "中國獲得全球讚譽,世界人民大團結萬歲,text", Field.Store.YES,
Field.Index.TOKENIZED);
doc2.add(field1);
field2 = new Field(ArticleText, "中國上海世博館雄踞東方,傲視全球........,roams,OpenOffice",
Field.Store.YES, Field.Index.TOKENIZED);
doc2.add(field2);
field3 = new Field(ArticleTime, "2010",
Field.Store.YES, Field.Index.TOKENIZED);
doc2.add(field3);
/*
*
*
*/
writer2.addDocument(doc2);

// 在這裏可以添加其他文件
//writer2.optimize();
/* 關閉 */
writer2.close();
}

public String searchIndex() throws Exception {
LuceneTest.index();
String keywords=getRequest().getParameter("serchString");
/* 創建一個搜索,搜索剛纔創建的目錄下的索引 */
IndexSearcher indexSearcher = new IndexSearcher(path);
/* 在這裏我們只需要搜索一個目錄 */
IndexSearcher indexSearchers[] = { indexSearcher };
/* 我們需要搜索兩個域ArticleTitle, ArticleText裏面的內容 */
String[] fields = {ArticleTitle,
ArticleText ,ArticleTime};
/* 下面這個表示要同時搜索這兩個域,而且只要一個域裏面有滿足我們搜索的內容就行
BooleanClause.Occur[]數組,它表示多個條件之間的關係,BooleanClause.Occur.MUST表示and,
BooleanClause.Occur.MUST_NOT表示not,BooleanClause.Occur.SHOULD表示or.
1、MUST和MUST表示“與”的關係,即“並集”。
2、MUST和MUST_NOT前者包含後者不包含。
3、MUST_NOT和MUST_NOT沒意義
4、SHOULD與MUST表示MUST,SHOULD失去意義;
5、SHOUlD與MUST_NOT相當於MUST與MUST_NOT。
6、SHOULD與SHOULD表示“或”的概念*/
BooleanClause.Occur[] clauses = { BooleanClause.Occur.SHOULD,
BooleanClause.Occur.SHOULD,BooleanClause.Occur.SHOULD};
/*
* MultiFieldQueryParser表示多個域解析,
* 同時可以解析含空格的字符串,如果我們搜索"上海 中國"
*/
Analyzer analyzer=new IK_CAnalyzer();
Query multiFieldQuery = MultiFieldQueryParser.parse(keywords, fields, clauses,
analyzer);
Query termQuery= new TermQuery(new Term(ArticleTitle, keywords));//詞語搜索,完全匹配,搜索具體的域

Query wildqQuery=new WildcardQuery(new Term(ArticleTitle,keywords));//通配符查詢

Query prefixQuery=new PrefixQuery(new Term(ArticleText,keywords));//字段前綴搜索

Query fuzzyQuery=new FuzzyQuery(new Term(ArticleText,keywords));//相似度查詢,模糊查詢比如OpenOffica,OpenOffice

Query rangQuery=new RangeQuery(new Term(ArticleTime,keywords), new Term(ArticleTime,keywords), true);//數字範圍查詢
/* Multisearcher表示多目錄搜索,在這裏我們只有一個目錄 */
MultiSearcher searcher = new MultiSearcher(indexSearchers);
//多條件搜索
BooleanQuery multiQuery=new BooleanQuery();

multiQuery.add(wildqQuery, BooleanClause.Occur.SHOULD);
multiQuery.add(multiFieldQuery, BooleanClause.Occur.SHOULD);
multiQuery.add(termQuery, BooleanClause.Occur.SHOULD);
multiQuery.add(prefixQuery, BooleanClause.Occur.SHOULD);
multiQuery.add(fuzzyQuery, BooleanClause.Occur.SHOULD);
multiQuery.add(rangQuery, BooleanClause.Occur.SHOULD);

Sort sort=new Sort(ArticleTime);//排序
/* 開始搜索 */
Hits h = searcher.search(multiQuery,sort);
String highTitle="";
String highText="";
List<String> list=new ArrayList<String>();
/* 把搜索出來的所有文件打印出來 */
for (int i = 0; i < h.length(); i++) {
//打印出文件裏面ArticleTitle域裏面的內容
String title=h.doc(i).get(ArticleTitle);
// 打印出文件裏面ArticleText域裏面的內容
String text=h.doc(i).get(ArticleText);
SimpleHTMLFormatter format=new SimpleHTMLFormatter("<b><font color='red'>","</font></b>");
Highlighter light=new Highlighter(format, new QueryScorer(multiQuery));//高亮
light.setTextFragmenter(new SimpleFragmenter(200));
if(title!=null)
{
TokenStream stream=analyzer.tokenStream(ArticleTitle, new StringReader(title));
highTitle=light.getBestFragment(stream, title);
System.out.println(highTitle);
}
if(text!=null)
{
TokenStream streamText=analyzer.tokenStream(ArticleText, new StringReader(text));
highText=light.getBestFragment(streamText, text);
System.out.println(highText);
}
//爲了在頁面好遍歷,把它放入集合中
if(highTitle!=null)
{
list.add("標題中包含關鍵字:"+highTitle+"<br/>");
}
if(highText!=null)
{
list.add("內容中包含關鍵字:"+highText+"<br/>");
}


}
getRequest().setAttribute("list",list);
/* 關閉 */
searcher.close();
return SUCCESS;
}
public String goToSearch()
{
return SUCCESS;
}

// 通配符搜索 WildcardQuery
// 通配符包括’?’匹配一個任意字符和’*’匹配零個或多個任意字符,例如你搜索’use*’,你可能找到’user’或者’uses’:
public static void wildcardSearcher() throws Exception{
index();
IndexSearcher searcher = new IndexSearcher(path);

// 與正則一樣,*代表0個或多個字母,?代表0個或一個字母
// WildcardQuery與QueryParser不同的是:WildcardQuery的前綴可以爲*,而QueryParser不行
Query query = new WildcardQuery(new Term(ArticleText,"te*"));

Hits hits = searcher.search(query);

printResult(hits);

searcher.close();
}
public static void printResult(Hits hits) throws IOException{
for(int i = 0; i < hits.length(); i++){
Document d = hits.doc(i);
String title=d.get(ArticleTitle);
String text=d.get(ArticleText);
String time=d.get(ArticleTime);
if(title!=null)
{
System.out.println(title);
}
if(text!=null)
{
System.out.println(text);
}
if(time!=null)
{
System.out.println(time);
}

}
}
public static void main(String[] args) throws Exception {
LuceneTest test=new LuceneTest();
test.wildcardSearcher();
LuceneTest .searchIndex();
}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章