用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)
        
{
            
#region Lucene Code
             IndexWriter writer
= new IndexWriter(indexDir, new StandardAnalyzer(), true);
             writer.SetUseCompoundFile(
false);
            
#endregion


             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)
            
{
               
#region Lucene Code
                 Document doc
= new Document();
                 Console.WriteLine(
"Indexing {0} ", fi.FullName);
                 doc.Add(Field.Text(
"contents", new StreamReader(fi.FullName) as TextReader));
                 doc.Add(Field.Keyword(
"filename", fi.FullName));
                 writer.AddDocument(doc);
                
#endregion

             }

             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)
        
{
            
#region Lucene Code
             IndexSearcher _is
= new IndexSearcher(dir);
             Query query
= QueryParser.Parse(q, "contents", new StandardAnalyzer());
             DateTime start
= DateTime.Now;
             Hits hits
= _is.Search(query);
             DateTime end
= DateTime.Now;
            
#endregion


             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的朋友赶快试试吧. 感谢关注!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值