摘要:Lucene.Net 使用 Or 運算子
2015/1/21 更新
接下來我們將介紹 Lucene.Net 的運算子 " Or " 的幾個方式 ,
初始動作 : 一開始我們仍然得來 Build 我們自己的 Index
public void BuildIndex()
{
//從App_Data底下讀入Index檔案 , 若沒有會自動建立
DirectoryInfo dirInfo = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory.ToString() + "\\App_Data");
FSDirectory dir = FSDirectory.Open(dirInfo);
IndexWriter iw = new IndexWriter(dir, new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30),true, IndexWriter.MaxFieldLength.UNLIMITED);
Document doc1 = new Document();
Field field3 = new Field("ID", "sherlock", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.NO);
Field field4 = new Field("DESC", "但是Sherlock是專業PG", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.NO);
doc1.Add(field3);
doc1.Add(field4);
iw.AddDocument(doc1);
//這裡將會寫進一份文件,而文件包含許多field(屬性),你可以決定這些屬性是否需要被索引
Document doc = new Document();
Field field = new Field("ID", "holmes", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.NO);
Field field2 = new Field("DESC", "但是holmes是專業PG", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.NO);
doc.Add(field);
doc.Add(field2);
iw.AddDocument(doc);
iw.Optimize();
iw.Commit();
//IndexWriter有實作IDisposable ,
//表示握有外部資源,所以記的得Close
iw.Close();
}
DEMO 1 : 使用 BooleanQuery
public void SearchByBQ(string keyWord)
{
string indexPath = AppDomain.CurrentDomain.BaseDirectory.ToString() + "\\App_Data\\";
DirectoryInfo dirInfo = new DirectoryInfo(indexPath);
FSDirectory dir = FSDirectory.Open(dirInfo);
IndexSearcher search = new IndexSearcher(dir, true);
QueryParser parser = new QueryParser(Lucene.Net.Util.Version.LUCENE_30, "DESC", new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30));
BooleanQuery booleanQuery = new BooleanQuery();
Query query1 = new TermQuery(new Term("ID", "holmes"));
Query query2 = new TermQuery(new Term("ID", "sherlock"));
//Occur.Should 表示 Or , Must 表示 and 運算子
booleanQuery.Add(query1,Occur.SHOULD);
booleanQuery.Add(query2, Occur.SHOULD);
Query query = parser.Parse(keyWord);
// 開始搜尋
var hits = search.Search(query, null, search.MaxDoc).ScoreDocs;
foreach (var res in hits)
{
Response.Write(string.Format("ID:{0} / DESC{1}"
, search.Doc(res.Doc).Get("ID").ToString()
, search.Doc(res.Doc).Get("DESC").ToString() + "
"));
}
}
DEMO 2 : 使用字串
Search("ID:holmes ID:sherlock");
public void Search(string KeyWord) {
string indexPath = AppDomain.CurrentDomain.BaseDirectory.ToString() + "\\App_Data\\";
DirectoryInfo dirInfo = new DirectoryInfo(indexPath);
FSDirectory dir = FSDirectory.Open(dirInfo);
IndexSearcher search = new IndexSearcher(dir, true);
// 針對 DESC 欄位進行搜尋
QueryParser parser = new QueryParser(Lucene.Net.Util.Version.LUCENE_30, "DESC", new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30));
// 搜尋的關鍵字
Query query = parser.Parse(KeyWord);
// 開使搜尋
var hits = search.Search(query, null, search.MaxDoc).ScoreDocs;
foreach (var res in hits)
{
Response.Write(string.Format("ID:{0} / DESC{1}",search.Doc(res.Doc).Get("ID").ToString()
,search.Doc(res.Doc).Get("DESC").ToString() + "
"));
}
}
DEMO 1 的做法有個限制 , 那就是 BooleanQuery 所能 Add 的數目預設為 1024 ,
使用 IL 查看後如下 :
Step1 :
public virtual void Add(Query query, Occur occur)
{
this.Add(new BooleanClause(query, occur));
}
Step2 : 這時可以看到有 BooleanQuery._maxClauses 的限制
public virtual void Add(BooleanClause clause)
{
if (this.clauses.Count >= BooleanQuery._maxClauses)
{
throw new BooleanQuery.TooManyClauses();
}
this.clauses.Add(clause);
}
Step3 : _maxClauses 被定義成1024
private static int _maxClauses = 1024;
若要增加 Caluse 的數目 , 可以設定下面的值
BooleanQuery.MaxClauseCount = value