用Lucene.Net轻松创建最简单的搜索引擎

Lucene是当下最受欢迎的Java开源搜索引擎开发包. 其实从本质上说, 它就是一个索引和检索的软件系统.
在Lucene中有一种特定的类型: Document, 它是一个Key-Value类型的集合. 我们只要将需要被索引的内容填入进去, Lucene就能够自动为其建立索引, 并且提供搜索. 因此, 通过Document, Lucene可以索引任何类型.

前几天一个做职位信息搜索的朋友让我给他的搜索引擎提提意见, 我试用后发现他其实需要一个很好的索引/检索系统来改善搜索效率. 于是就推荐Lucene.Net(Lucene.Net是Lucene的.Net版本)给他用.

用Lucene.Net创建搜索引擎其实十分简单, 为了让他更加容易上手, 我写了一个文件搜索引擎作为Demo:

Demo包含两个部分:
DirIndexer 和 DirSearcher

顾名思义, DirIndexer是用来创建索引的程序, 而DirSearcher是用来进行搜索的程序.

先说DirIndexer. 其中, 我们要用到Lucene.Net的5个核心类:
IndexWriter
Directory
Analyzer
Document
Field
它们之间的关系如下:

实现代码如下:
using System;
using System.IO;
using Lucene.Net.Index;
using Lucene.Net.Documents;
using Lucene.Net.Analysis.Standard;

namespace DirIndexer
{
    
class Indexer
    
{
        [STAThread]
        
static void Main(string[] args)
        
{
            
/* *
             * args[0]: Index Directory;
             * args[1]: Data Directory;
             * args[2]: Pattern, like "*.txt", "*.cs", etc.;
             * 
*/

            
            
new Indexer(args[0], args[1], args[2]);
        }


        
public Indexer(string indexDir, string dataDir, string pattern)
        
{
            
Lucene Code

            DateTime start 
= DateTime.Now;
            DoIndex(writer, 
new DirectoryInfo(dataDir), pattern);
            DateTime end 
= DateTime.Now;
            
int docNum = writer.DocCount();
            Console.WriteLine(
"Index Finished. {0} Documents takes {1} second.", docNum, ((TimeSpan)(end - start)).TotalSeconds);
            writer.Optimize();
            writer.Close();
        }


        
private static void DoIndex(IndexWriter writer, DirectoryInfo dir, string pattern)
        
{
            FileInfo[] files 
= dir.GetFiles(pattern);
            
foreach(FileInfo fi in files)
            
{
                
Lucene Code 
            }

            DirectoryInfo[] dirs 
= dir.GetDirectories();
            
foreach(DirectoryInfo di in dirs)
            
{
                DoIndex(writer, di, pattern);
            }

        }

    }

}

其中Lucene Code标签中包含的就是所有和Lucene.Net相关的代码, 一共6行有效代码, 其他的都是用来遍历文件夹等逻辑的代码.
OK, 运行一下, 命令行参数如下:
args[0] = "f:\index" //创建索引的位置
args[1] = "f:\工作区\myprojects" //要索引的文件位置
args[2] = "*.cs" //要索引的文件类型

1594个文档, 一共用时91秒, 平均每秒17个文档. 我用的是一台CPU 1G, 内存512M的机器, 呵呵, 比较古董, 大家的应该比我的快才对.

下面看看DirSearcher.在搜索的时候, 我们也要用到6个核心类:
IndexSearcher
Term
Query
TermQuery
QueryParser
Hits

其关系如下:

其中实线和虚线分别代表了两种不同的搜索实现方式.
代码如下:

using System;
using Lucene.Net.Documents;
using Lucene.Net.Search;
using Lucene.Net.Analysis.Standard;
using Lucene.Net.QueryParsers;

namespace DirSearcher
{
    
class Searcher
    
{
        [STAThread]
        
static void Main(string[] args)
        
{
            
/* *
             * args[0]: Index Directory
             * 
*/

            Searcher s 
= new Searcher(args[0]);
            Console.WriteLine(
"Please input query string:");
            
string query = "";
            
while((query = Console.ReadLine()) != "")
            
{
                Hits hits 
= s.Search(query);
                Console.WriteLine(
"Press ENTER to see details:");
                Console.ReadLine();
                
for(int i = 0; i < hits.Length(); i++)
                
{
                    Document doc 
= hits.Doc(i);
                    Console.WriteLine(doc.Get(
"filename"));
                }

                Console.WriteLine(
"----------------------------------------------------");
            }

        }


        
private string dir = "";

        
public Searcher(string indexDir)
        
{
            dir 
= indexDir;
        }


        
public Hits Search(string q)
        
{
            
Lucene Code

            Console.WriteLine(
"Search Finished. {0} Results takes {1} second:", hits.Length(), ((TimeSpan)(end - start)).TotalSeconds);
            
return hits;
        }

    }

}


和DirIndexer一样, Lucene Code标记中就是Lucenen.Net的代码, 一共3行有效代码.
OK, 运行一下:
args[0] = "f:\index" //创建索引的位置


怎么样? 十分简单吧. 这就是Lucene的力量. Demo的完整代码在下面, 希望了解Lucene的朋友赶快试试吧. 感谢关注!

 DirIndex & DirSearcher

posted @ 2007-04-01 11:58  Ivan Zou  阅读(1417)  评论(1编辑  收藏  举报