数日間の多忙な作業を経て、ようやく簡単な全文検索を実装しました。Lucene.Net
とは何ですか? Lucene.Net では何ができるのでしょうか?そしてそれをどうやって行うかという問題は?最後に、全文検索を実装する Lucene.Net の例を示します。
1. Lucene.Net とは何ですか?
Lucene.net はもともとオープン ソース プロジェクトで、その後商業化に転じました。Lucene.net 2.0 もリリースされましたが、金銭的には D. Lucene.net の運命は、バージョン 1.6 の後にリリースされた 2.0 から始まった FreeTextBox に似ています。 5. 商用ルート、2.0 は DLL 形式で無料バージョンを提供し、ソース コード バージョンは商用ライセンスを購入する必要があります。ただし、バージョン 1.6.5 のソース コードはそのままで、ほとんどの内部詳細を参照できます。ただし、バージョン 2.0 では、Mozilla ブラウザの追加サポートは、生成される HTML および JavaScript スクリプトを通じてのみ表示されます。
Lucene は、Java の世界で一般的に使用されるインデックス API であり、それが提供するメソッドを使用して、テキスト マテリアルのインデックスを作成し、検索を提供できます。 (参考: NLucene と Lucene .NET) NLucene は、最初の .net ポートであり、.net 命名規則とクラス ライブラリ設計を使用する .net スタイルのバージョンです。ただし、エネルギー上の理由により、NLucene プロジェクトのリーダーは 1.2beta バージョンのみをリリースしました。 Lucene.NET プロジェクトが登場した後、NLucene に対する新しい計画はありませんでした。
Lucene.NET は当初、最新の .net Lucene 移植であると主張していましたが、その主な目的は、名前付けに関して .net の提案を採用しただけでした。その主な目標は、インデックス形式に互換性を持たせることでした。目的は、名前が似ていること (大文字と小文字など、いくつかの違いがあるだけ) であり、開発者が Java Lucene 関連のコードと情報を使用しやすくすることです。
Lucene.NET プロジェクトがいつオープンソース計画を断念してビジネスに転じたのかはわかりません。実際には、SourceForge 上のオープンソース ファイルが削除されました。同時に、Lucene.NET に抗議して、dotLucene プロジェクトが SourceForge に登場しました。dotLucene は、Lucene.NET コードをほぼそのままの状態で開始しました。 ( https://sourceforge.net/forum/forum.php?thread_id=1153933&forum_id=408004 )。
率直に言うと、Lucene.Net は情報検索機能ライブラリ (ライブラリ) であり、これを使用してアプリケーションにインデックス作成機能や検索機能を追加できます。
ただし、Lucene ユーザーは全文検索に関する深い知識を持っている必要はありません。
ただし、Lucene が Google や Baidu のような検索
エンジンであることを期待しないでください。ツール、ライブラリとも言えます。この API は、インデックス作成と検索機能をカプセル化したシンプルで使いやすい API であり、非常に便利です。アプリケーション開発者 (非専門の検索エンジン開発者) は、その機能で十分に満足できます。
2. Lucene.Net では何ができるのですか?
Lucene は、データ ソースの形式に関係なく、つまり、MS Word、HTML、PDF など、あらゆるデータを分析して利用できます。その他 テキスト コンテンツを抽出できる限り、どのような形式のファイルでも使用できます。Lucene を使用してインデックスを付けたり、検索したりできます
。
簡単に言うと、インデックスの作成とインデックスの使用です。インデックスの作成は、検索対象のデータ ソースの情報をキー情報として保存または分析することであり、検索用のマークを残すことは、テーブルを作成することに似ています。 Wordの内容(個人的な理解)、インデックスの利用とは、検索時にインデックス情報を基にデータソースを分析し、必要な情報を抽出することです。
例を見てください:
インデックスを作成するための
public class IntranetIndexer
{
/**/////インデックスライター
private IndexWriter ライター
// インデックスに書き込まれるファイルのルート ディレクトリ。
private string docRootDirectory
// 一致するファイル形式
プライベート文字列[]パターン;
/**//// <概要>
/// インデックス ライターを初期化します。ディレクトリはインデックスが作成されるディレクトリです。true は、インデックス ファイルが存在しない場合はインデックス ファイルが再作成されます。上書きされました。
/// </概要>
/// <param name="directory">インデックスを作成するディレクトリが渡されます。ディレクトリが存在しない場合は、自動的に作成されることに注意してください。</param>
publicIntranetIndexer(文字列ディレクトリ)
{
Writer = new IndexWriter(ディレクトリ, new StandardAnalyzer(), true);
Writer.SetUseCompoundFile(true);
}
public void AddDirectory(DirectoryInfo ディレクトリ、文字列 [] パターン)
{
this.docRootDirectory = ディレクトリ.フルネーム;
this.pattern = パターン;
addSubDirectory(ディレクトリ);
}
private void addSubDirectory(DirectoryInfo ディレクトリ)
{
for(int i=0;i<パターン .Length ;i++)
{
foreach (ディレクトリ内の FileInfo fi.GetFiles(pattern[i]))
{
AddHtmlDocument(fi.FullName);
}
}
foreach (directory.GetDirectories() 内の DirectoryInfo)
{
addサブディレクトリ(di);
}
}
public void AddHtmlDocument(文字列パス)
{
文字列 exname=Path.GetExtension (パス);
ドキュメント doc = new Document();
文字列html;
if(exname.ToLower ()==".html" ||exname .ToLower ()==".htm"||exname .ToLower ()==".txt")
{
using(StreamReader sr=new StreamReader (パス,System .Text .Encoding .Default ))
{
html = sr.ReadToEnd();
}
}
それ以外
{
using (StreamReader sr = new StreamReader(path, System.Text.Encoding.Unicode ))
{
html = sr.ReadToEnd();
}
int
reversePathStartsAt = this.docRootDirectory.EndsWith("\") ? this.docRootDirectory.Length : this.docRootDirectory.Length + 1;
文字列相対パス = path.Substring(relativePathStartsAt);
文字列タイトル=パス.GetFileName(パス);
// Web ページかどうかを判断し、タグを削除します。それ以外の場合は使用しないでください
if(exname.ToLower ()==".html" ||exname .ToLower ()==".htm")
{
doc.Add(Field.UnStored("テキスト", parseHtml(html)));
}
それ以外
{
doc.Add (フィールド .UnStored ("text",html));
}
doc.Add(Field.Keyword("パス", 相対パス));
//doc.Add(Field.Text("タイトル", getTitle(html)));
doc.Add (フィールド .Text ("title",title));
Writer.AddDocument(doc);
}
/**//// <概要>
/// Web ページからタグを削除します
/// </概要>
/// <param name="html">Web ページ</param>
/// <returns>削除された Web ページのテキストを返します</returns>
プライベート文字列parseHtml(文字列html)
{
string temp = Regex.Replace(html, "<[^>]*>", "");
return temp.Replace(" ", " ");
}
/**//// <概要>
/// ページタイトルを取得する
/// </概要>
/// <param name="html"></param>
/// <戻り値></戻り値>
プライベート文字列 getTitle(string html)
{
Match m = Regex.Match(html, "<title>(.*)</title>");
if (m.Groups.Count == 2)
m.Groups[1].Value を返します。
"ドキュメントのタイトルが不明" を返します。
}
/**//// <概要>
/// インデックスを最適化してライターを閉じる
/// </概要>
public void Close()
{
Writer.Optimize();
Writer.Close();
}
まず Document オブジェクトを作成し、次にいくつかの属性 Field を Document オブジェクトに追加します。Document オブジェクトは仮想ファイルと考えることができ、この仮想ファイルから情報が取得されます。この仮想ファイルを記述するメタデータと見なされます
。
その中には、フィールドには 4 つのタイプが含まれます: キーワーク
このタイプのデータは分析されませんが、インデックス付けされ、インデックスに保存されます。
インデックスなし
このタイプのデータは分析またはインデックス付けされませんが、インデックスに保存されます。
未保管
UnIndexed の逆で、分析およびインデックス付けは行われますが、保存されません。
文章
UnStored と同様です。値のタイプが文字列の場合は、UnStored と同様に保存されません。
最後に、各ドキュメントがインデックスに追加されます。
以下はインデックスの検索です
//インデクサーを作成する
IndexSearcher サーチャー = 新しい IndexSearcher(indexDirectory);
//検索用のインデックスのテキストフィールドを解析します
クエリ query = QueryParser.Parse(this.Q, "text", new StandardAnalyzer());
//検索結果をヒット数に入れる
ヒット数 = searcher.Search(query);
//検索されたレコードの総数に関する統計
this.total = ヒット数.Length();
//ハイライト
QueryHighlightExtractor ハイライター = new QueryHighlightExtractor(query, new StandardAnalyzer(), "<font color=red>", "</font>");
最初のステップでは、IndexSearcher を使用して後続の検索のためにインデックス ファイルを開きます。パラメータはインデックス ファイルのパスです。2
番目のステップでは、QueryParser を使用して、より読みやすいクエリ ステートメント (クエリ ワード lucene など) を変換します。高度なメソッド lucene AND.net) を Lucene によって内部的に使用されるクエリ オブジェクトに追加します。3
番目のステップでは、検索が実行され、結果がヒット コレクションに返されます。Lucene はすべての結果を一度にヒットに入れるのではありません。スペースを考慮して、
検索結果は処理されてページに表示されます:
for (int i = startAt; i < resultsCount; i++)
{
ドキュメント doc = hits.Doc(i);
文字列パス = doc.Get("パス");
文字列位置 =Server.MapPath("ドキュメント")+" \"+パス;
文字列 exname=Path.GetExtension (パス);
文字列プレーンテキスト;
文字列 str=doc.Get ("タイトル");
if(exname==".html" || exname ==".htm" || exname ==".txt")
{
using (StreamReader sr = new StreamReader(location, System.Text.Encoding.Default))
{
plainText = parseHtml(sr.ReadToEnd());
}
}
それ以外
{
using (StreamReader sr = new StreamReader(location, System.Text.Encoding.Unicode ))
{
plainText = sr.ReadToEnd();
}
}
//DataTable は行を追加します
DataRow 行 = this.Results.NewRow();
row["タイトル"] = doc.Get("タイトル");
string IP=Request.Url.Host;//サーバーIPを取得します
//リクエスト.URL.ポート;
row["path"]=@" http://"+IP+"/WebUI/Search/documents/"+path ;
row["サンプル"] = ハイライター.GetBestFragments(plainText, 80, 2, "");
this.Results.Rows.Add(行);
}
searcher.Close();//Lucene.Net についてより高度で包括的かつ深く理解したい場合は、Web サイト
http: //blog.tianya.cn/blogger/view_blog.asp?BlogName=aftaft