Lucene.Net 使用 Or 運算子

摘要: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