2012-10-04

[C#] Lucene.net - 合併搜尋條件(交集搜尋條件、聯集搜尋條件) BooleanQuery

 

透過 Lucene.net  進行全文檢索是非常溫馨的,但是有時候我們透過檢索的條件會非常的多樣化

這時候該怎麼解決呢? 其實你大可以經過搜尋後 在把答案再濾過一次

但是如果你第一個條件下去,得到的答案依然是千萬筆該怎麼辦呢?!

所以多重條件的需求是必然的…

資料介紹

索引中有兩筆資料

2012-10-04_134150

其中都帶有當麻的字樣 這時候我們怎麼進行合併搜尋呢?!

如果我只想找到資料中有 當麻 也有 左手的資料 我該怎麼進行查詢..

// 針對 Memo 欄位進行搜尋 條件 1
Query query1 = new TermQuery(new Term("Memo", txtKeyword.Text)); // 詞語搜索
// 針對 Memo 欄位進行搜尋 條件 2
Query query2 = new TermQuery(new Term("Memo", txtKeyword2.Text)); // 詞語搜索
// 搜尋的關鍵字
 
BooleanQuery query = new BooleanQuery();
 
query.Add(query1, BooleanClause.Occur.MUST);
query.Add(query2, BooleanClause.Occur.MUST);
 
// 開始搜尋
var hits = search.Search(query, null, search.MaxDoc()).ScoreDocs;

完整 C# Code :



// 啟用監看
 Stopwatch sw = new Stopwatch();
 sw.Start();
 
 // 讀取索引
 string indexPath = AppDomain.CurrentDomain.BaseDirectory.ToString() + "\\Index1\\";
 DirectoryInfo dirInfo = new DirectoryInfo(indexPath);
 FSDirectory dir = FSDirectory.Open(dirInfo);
 IndexSearcher search = new IndexSearcher(dir, true);
 // 針對 Memo 欄位進行搜尋 條件 1
 Query query1 = new TermQuery(new Term("Memo", txtKeyword.Text)); // 詞語搜索
 // 針對 Memo 欄位進行搜尋 條件 2
 Query query2 = new TermQuery(new Term("Memo", txtKeyword2.Text)); // 詞語搜索
 // 搜尋的關鍵字
 
 BooleanQuery query = new BooleanQuery();
 
 query.Add(query1, BooleanClause.Occur.MUST);
 query.Add(query2, BooleanClause.Occur.MUST);
 
 // 開始搜尋
 var hits = search.Search(query, null, search.MaxDoc()).ScoreDocs;
 
 sw.Stop();
 Response.Write("花費時間:" + sw.Elapsed + "<br /><hr />");
 Response.Write("資料比數:" + hits.Length + "<br /><hr />");
 Response.Write("Result:<br />");
 
 foreach (var res in hits)
 {
     Response.Write("Id:" + search.Doc(res.doc).Get("Id") + "  Memo=" + search.Doc(res.doc).Get("Memo").ToString().Replace(txtKeyword.Text, "<span style='color:red'>" + txtKeyword.Text + "</span>") + "<br />");
 }

這時搜尋出來的答案是:


2012-10-04_134217


OK~ 答案正確 這時候你一定會問 其中的 BooleanClause.Occur.MUST  是幹嘛的


看一下文件:


MUST


Use this operator for clauses that must appear in the matching documents. 使用此運算條款一定要出現在文件中


MUST_NOT


Use this operator for clauses that must not appear in the matching documents. 使用此運算條款一定 不能 出現在文件中


SHOULD


Use this operator for clauses that should appear in the matching documents. 使用此運算條款一定 應該 出現在文件中


 


看一下測試結果:


MUST + MUST 就是等於交集運算元 AND , &&



// 針對 Memo 欄位進行搜尋 條件 1
Query query1 = new TermQuery(new Term("Memo", "當麻")); // 詞語搜索
// 針對 Memo 欄位進行搜尋 條件 2
Query query2 = new TermQuery(new Term("Memo", "左手")); // 詞語搜索
// 搜尋的關鍵字
 
BooleanQuery query = new BooleanQuery();
 
query.Add(query1, BooleanClause.Occur.MUST);
query.Add(query2, BooleanClause.Occur.MUST);

結果:


2012-10-04_134300


MUST + MUST_NOT 就是不能有



// 針對 Memo 欄位進行搜尋 條件 1
Query query1 = new TermQuery(new Term("Memo", "當麻")); // 詞語搜索
// 針對 Memo 欄位進行搜尋 條件 2
Query query2 = new TermQuery(new Term("Memo", "左手")); // 詞語搜索
// 搜尋的關鍵字
 
BooleanQuery query = new BooleanQuery();
 
query.Add(query1, BooleanClause.Occur.MUST);
query.Add(query2, BooleanClause.Occur.MUST_NOT);

結果:


2012-10-04_134321


MUST + SHOULD 就是或也就是聯集 運算元等於 ||   or



// 針對 Memo 欄位進行搜尋 條件 1
Query query1 = new TermQuery(new Term("Memo", "當麻")); // 詞語搜索
// 針對 Memo 欄位進行搜尋 條件 2
Query query2 = new TermQuery(new Term("Memo", "左手")); // 詞語搜索
// 搜尋的關鍵字
 
BooleanQuery query = new BooleanQuery();
 
query.Add(query1, BooleanClause.Occur.MUST);
query.Add(query2, BooleanClause.Occur.SHOULD);

結果:


2012-10-04_134344


這樣我相信,面對各種搜尋挑戰就難不倒大家了…