Luceneにおけるdocument(レコード)に対するCURD操作~は分散全文検索設計
16138 ワード
Lucene.Netは.Net環境の中で比較的に強い全文検索ツール、それはJAVAから中継してきたので、.Netバージョンのluceneは機能的にもjava版のluceneに劣らない.今日は主にluceneインデックスファイルの更新方法について説明します.
インデックスファイル全体(cfsファイル)が更新を上書きします.利点:簡単、欠点:サーバとインタラクティブではありませんが、インデックスファイルを生成する際にIOに大きな影響を及ぼし、フロントlucene情報はデータベースと同期していません.
インデックスファイルは必要に応じて更新され(documentレコードに対してcurd操作を行う)、利点:データベースと同期し、欠点:サーバとのインタラクションが多く、curdのセキュリティを重視する必要がありますが、これは必要です.
次に、第2のインデックスファイルを必要に応じて更新する場合について説明します.
追加document(レコード):データベーステーブルにinsert操作がある場合、luceneも対応するinsert操作を行う必要があります.これが追加です.IndexWriterにはAddDocumentメソッドがありますが、何も言うことはありません.メソッドに従って署名して値を変えるだけでいいので、操作が完了したらIndexWriterにOptimizeとCloseを行うことに注意してください.
レコードの削除(document):この操作にはいくつかの点に注意する必要があります.
1削除するレコードの根拠は一意性を持つべきで、このように削除してこそ意味があり、このフィールドはluceneが格納する時にANALYZEDである必要があり、つまり検索することができる.
2削除時の条件は、TermではなくQueryを使用したほうがいいです.私は多くのテストをした結果、Term条件はいつも使用しないことを証明しました.
削除されたコードは次のとおりです.
更新操作は事実上、まず記録を削除し、新しい記録を追加すればいいのですが、IndexWriterが提供してくれたUpdateDocumentsはもっとコピーしているような気がしますので、使用することをお勧めしません.
手動で削除して追加してこのupdate操作を完了します.
OK、これはインデックスファイルに対して必要に応じた操作を行い、後で私のluceneアーキテクチャを文章に整理して、みんなの討論に供します.
インデックスファイル全体(cfsファイル)が更新を上書きします.利点:簡単、欠点:サーバとインタラクティブではありませんが、インデックスファイルを生成する際にIOに大きな影響を及ぼし、フロントlucene情報はデータベースと同期していません.
インデックスファイルは必要に応じて更新され(documentレコードに対してcurd操作を行う)、利点:データベースと同期し、欠点:サーバとのインタラクションが多く、curdのセキュリティを重視する必要がありますが、これは必要です.
次に、第2のインデックスファイルを必要に応じて更新する場合について説明します.
追加document(レコード):データベーステーブルにinsert操作がある場合、luceneも対応するinsert操作を行う必要があります.これが追加です.IndexWriterにはAddDocumentメソッドがありますが、何も言うことはありません.メソッドに従って署名して値を変えるだけでいいので、操作が完了したらIndexWriterにOptimizeとCloseを行うことに注意してください.
1 [WebMethod]
2 public int AppendLuceneDocument(string primaryKey, string id, string name, string info, string categoryName, string propertyName, string module, string passKey)
3 {
4 int flag = 0;
5 try
6 {
7 dirInfo = Directory.CreateDirectory(this.GetIndexPath(ConfigurationManager.AppSettings[module]));
8 directory = LuceneIO.FSDirectory.Open(dirInfo);
9 IndexWriter writer = new IndexWriter(directory, new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29), false, IndexWriter.MaxFieldLength.UNLIMITED);
10 Document doc = new Document();
11 doc.Add(new Field("PrimaryKey", primaryKey, Field.Store.YES, Field.Index.ANALYZED));
12 doc.Add(new Field("ID", id, Field.Store.YES, Field.Index.NO));
13 doc.Add(new Field("Name", name, Field.Store.YES, Field.Index.ANALYZED));
14 doc.Add(new Field("Info", info, Field.Store.YES, Field.Index.ANALYZED));
15 doc.Add(new Field("CategoryName", categoryName, Field.Store.YES, Field.Index.ANALYZED));
16 doc.Add(new Field("PropertyName", propertyName, Field.Store.YES, Field.Index.ANALYZED));
17 writer.AddDocument(doc);
18 writer.Optimize();
19 writer.Close();
20 flag = 1;
21 }
22 catch (Exception)
23 {
24
25 throw;
26 }
27 return flag;
28 }
レコードの削除(document):この操作にはいくつかの点に注意する必要があります.
1削除するレコードの根拠は一意性を持つべきで、このように削除してこそ意味があり、このフィールドはluceneが格納する時にANALYZEDである必要があり、つまり検索することができる.
2削除時の条件は、TermではなくQueryを使用したほうがいいです.私は多くのテストをした結果、Term条件はいつも使用しないことを証明しました.
削除されたコードは次のとおりです.
1 [WebMethod]
2 public int DeleteLuceneDocument(string primaryKey, string module, string passKey)
3 {
4 int flag = 0;
5 try
6 {
7 dirInfo = Directory.CreateDirectory(this.GetIndexPath(ConfigurationManager.AppSettings[module]));
8 directory = LuceneIO.FSDirectory.Open(dirInfo);
9 IndexWriter writer = new IndexWriter(directory, standardAnalyzer, false, IndexWriter.MaxFieldLength.UNLIMITED);
10 QueryParser parser = new QueryParser(Lucene.Net.Util.Version.LUCENE_29, "PrimaryKey", new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29));
11 Query query = parser.Parse(primaryKey);
12 writer.DeleteDocuments(query);
13 writer.Commit();
14 writer.Optimize();
15 writer.Close();
16 flag = 1;
17 }
18 catch (Exception)
19 {
20
21 throw;
22 }
23 return flag;
24 }
更新操作は事実上、まず記録を削除し、新しい記録を追加すればいいのですが、IndexWriterが提供してくれたUpdateDocumentsはもっとコピーしているような気がしますので、使用することをお勧めしません.
手動で削除して追加してこのupdate操作を完了します.
1 [WebMethod]
2 public int UpdateLuceneDocument(string primaryKey, string id, string name, string info, string categoryName, string propertyName, string module, string passKey)
3 {
4 int flag = 0;
5 try
6 {
7 dirInfo = Directory.CreateDirectory(this.GetIndexPath(ConfigurationManager.AppSettings[module]));
8 directory = LuceneIO.FSDirectory.Open(dirInfo);
9 IndexWriter writer = new IndexWriter(directory, new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29), false, IndexWriter.MaxFieldLength.UNLIMITED);
10 Document doc = new Document();
11 doc.Add(new Field("PrimaryKey", primaryKey, Field.Store.YES, Field.Index.ANALYZED));
12 doc.Add(new Field("ID", id, Field.Store.YES, Field.Index.NO));
13 doc.Add(new Field("Name", name, Field.Store.YES, Field.Index.ANALYZED));
14 doc.Add(new Field("Info", info, Field.Store.YES, Field.Index.ANALYZED));
15 doc.Add(new Field("CategoryName", categoryName, Field.Store.YES, Field.Index.ANALYZED));
16 doc.Add(new Field("PropertyName", propertyName, Field.Store.YES, Field.Index.ANALYZED));
17 QueryParser parser = new QueryParser(Lucene.Net.Util.Version.LUCENE_29, "PrimaryKey", new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29));
18 Query query = parser.Parse(primaryKey);
19 writer.DeleteDocuments(query);
20 writer.Commit();
21 writer.AddDocument(doc);
22 writer.Optimize();
23 writer.Close();
24 flag = 1;
25 }
26 catch (Exception)
27 {
28
29 throw;
30 }
31
32 return flag;
33 }
OK、これはインデックスファイルに対して必要に応じた操作を行い、後で私のluceneアーキテクチャを文章に整理して、みんなの討論に供します.