[PC] FlexLuceneのJapanese Analyzer(1/2)
FlexLuceneのJapanese Analyzerを使う(その1)
FlexLuceneとは
FlexLuceneは、IKVMを使ったApache Lucene(以下、Lucene)の.NET移植版です。IKVM自体が、Mono及び.NET FrameworkのJava仮想マシンの移植であり、FlexLuceneは、それを利用してLuceneを.NET Frameworkで実行させるものになります。Lucene自体は、オープンソースソフトウェアで、Javaで開発されている全文検索エンジンです。
Luceneとの出会い
Luceneは、いわゆる「インデックス型」の検索エンジンで、最初に検索する文書の単語情報等を抽出し(インデックス作成)、それを検索するものであり、強力な検索能力を有します。一度、インデックス作成してしまえば、検索スピードは、一瞬でできてしまいます。
Apache Lucene 入門 ~Java・オープンソース・全文検索システムの構築 中古価格 |
最初にLucene.NET
本題のFlexLuceneに入る前に、Luceneを知るきっかけを書きます。Luceneの.NET Frameworkへの実装は、FlexLuceneの他にも、Lucene.NETとというJavaのLuceneをC#等で使えるようにポーティングするプロジェクトがあります。そして、そのLucene.NETを使って日本語のJapaneseAnalyzerを実装し、利用する紹介記事が@IT(atmarkit)で紹介されました。これが、Luceneとの出会いです。この紹介記事を基に、Word文書や、PDF、txt、HTMLと様々なファイルの全文検索できるアプリケーションを作りました。
Lucene.NETの限界
ただ、Lucene.NETは、バージョンがLuceneのバージョン2.9.4を利用するものであり、使える新しいバージョンでも3.0.3のものでした。開発はその後ずっと止まっていました。流石に古くてASP.NET Framework 4.6等では、利用できず限界を感じていました。
.NET開発テクノロジ入門2016年版Visual Studio 2015対応版 中古価格 |
しかし、最近、Lucene.NETの新しいβバージョンが出たと言う記事を目にしました。バージョンは、Lucene 4.8であり、 .NET Framework 4.5.1, .NET Standard 1.5が利用できるものとなりました。途中までプログラムしたのですが、JapaneseAnalyzerは、まだ実装されていないことに気づきました。βバージョンということで、恨んでもしかたありません。やむを得ません。
FlexLuceneとの出会い
開発を諦めかけていたとき、FlexLuceneというIKVMを使った移植版があることを知りました。しかも、Lucene対応バージョンは、6.3、更にホームページ上では、日本語の対応も謳われていました。
Changes 6.3.0 - Port of Lucene 6.3.0 release. - Added support for Japanese analyzer.
これは、利用するしかないと思い、飛びつきました。
FlexLuceneのサンプルコード
では、ようやくサンプルコードを付けます。インデックスを作成するところまで確認しました。Visual Studio 2017 community editionで作成しています。nugetで、IKVMのモジュールをインストールし、FlexLuceneは、dllをダウンロードするものです。
using System; using System.Text; using System.Text.RegularExpressions; using System.IO; using FlexLucene.Analysis.Ja; using FlexLucene.Store; using FlexLucene.Index; using FlexLucene.Document; using java.nio.file; using java.io; namespace LNetTest { class Program { const string DATADIR = @"\\server\data"; const string INDEXDIR = @"c:\temp\ldn-index"; static void Main(string[] args) { java.nio.file.Path idx_path = FileSystems.getDefault().getPath(INDEXDIR); FSDirectory dir = FSDirectory.Open(idx_path); // テキストの解析方法(アナライザー)を定義 JapaneseAnalyzer analyzer = new JapaneseAnalyzer(); IndexWriterConfig config = new IndexWriterConfig(analyzer); IndexWriter writer = new IndexWriter(dir, config); String[] files = System.IO.Directory.GetFiles(DATADIR, "*.htm*", System.IO.SearchOption.AllDirectories); try { foreach (string file in files) { string title, content, f; title = ""; content = ""; f = file; HTMLParse(ref title, ref content, ref f); Field fldTitle = new StringField("title", title, FieldStore.YES); Field fldPlace = new StringField("place", f, FieldStore.YES); Field fldContent = new TextField("content", content, FieldStore.YES); doc.Add(fldTitle); doc.Add(fldPlace); doc.Add(fldContent); writer.AddDocument(doc); } } catch(System.IO.IOException ex) { System.Console.WriteLine(ex.ToString()); } //インデクサのクローズ writer.Close(); } /************************* * HTMLの解析 *************************/ private static void HTMLParse(ref string title, ref string content, ref string fileName) { StreamReader sr = new StreamReader(fileName, Encoding.GetEncoding("Shift_JIS")); string text = sr.ReadToEnd(); //正規表現パターンとオプションを指定してRegexオブジェクトを作成 Regex rTitle = new Regex("<title[^>]*>(.*?)</title>", RegexOptions.IgnoreCase | RegexOptions.Singleline); Regex rPre = new Regex("<body[^>]*>(.*?)</body>", RegexOptions.IgnoreCase | RegexOptions.Singleline); //TextBox1.Text内で正規表現と一致する対象をすべて検索 MatchCollection mcTitle = rTitle.Matches(text); MatchCollection mcPre = rPre.Matches(text); foreach (Match m in mcTitle) { title = m.Groups[1].Value; } foreach (Match m in mcPre) { content = m.Groups[1].Value; } } } }
このコードで、日本語の形態素解析されたインデックスが作成されました。
ここにたどり着くまでに遠回りをしたのですが、その遠回りに関しては、次に書きたいと思います。とりあえず動作したのでそれを備忘録として記載しておきます。
まとめ
Luceneの.NET移植版FlexLuceneで日本語解析とそのインデックスを作成することができるようになりました。FlexLuceneの開発者の皆様及び日本語形態素解析の開発者の皆様に感謝するとともに、まだ触れていない人に利用していただければ幸いです。